diff options
author | Martyn Capewell <martyn.capewell@arm.com> | 2022-05-04 11:27:51 +0100 |
---|---|---|
committer | Martyn Capewell <martyn.capewell@arm.com> | 2022-05-13 14:23:53 +0100 |
commit | 918eb5f50be35fecf5c8965e65d1ce062d79d9e9 (patch) | |
tree | 3ddb0284159f5ea240cbaaa2e4e53e61e772b966 | |
parent | 20a0a23235c6176109c30781cbb1de411b1bad80 (diff) | |
download | vixl-918eb5f50be35fecf5c8965e65d1ce062d79d9e9.tar.gz |
Simplify disassembler for already decoded mnemonics #3
Further simplification of the disassembler using mnemonics provided by the
decoder.
-rw-r--r-- | src/aarch64/disasm-aarch64.cc | 1062 |
1 files changed, 230 insertions, 832 deletions
diff --git a/src/aarch64/disasm-aarch64.cc b/src/aarch64/disasm-aarch64.cc index 22f1a335..1dd80936 100644 --- a/src/aarch64/disasm-aarch64.cc +++ b/src/aarch64/disasm-aarch64.cc @@ -1518,138 +1518,94 @@ void Disassembler::VisitMoveWideImmediate(const Instruction *instr) { } -#define LOAD_STORE_LIST(V) \ - V(STRB_w, "strb", "'Wt") \ - V(STRH_w, "strh", "'Wt") \ - V(STR_w, "str", "'Wt") \ - V(STR_x, "str", "'Xt") \ - V(LDRB_w, "ldrb", "'Wt") \ - V(LDRH_w, "ldrh", "'Wt") \ - V(LDR_w, "ldr", "'Wt") \ - V(LDR_x, "ldr", "'Xt") \ - V(LDRSB_x, "ldrsb", "'Xt") \ - V(LDRSH_x, "ldrsh", "'Xt") \ - V(LDRSW_x, "ldrsw", "'Xt") \ - V(LDRSB_w, "ldrsb", "'Wt") \ - V(LDRSH_w, "ldrsh", "'Wt") \ - V(STR_b, "str", "'Bt") \ - V(STR_h, "str", "'Ht") \ - V(STR_s, "str", "'St") \ - V(STR_d, "str", "'Dt") \ - V(LDR_b, "ldr", "'Bt") \ - V(LDR_h, "ldr", "'Ht") \ - V(LDR_s, "ldr", "'St") \ - V(LDR_d, "ldr", "'Dt") \ - V(STR_q, "str", "'Qt") \ - V(LDR_q, "ldr", "'Qt") +#define LOAD_STORE_LIST(V) \ + V(STRB_w, "'Wt") \ + V(STRH_w, "'Wt") \ + V(STR_w, "'Wt") \ + V(STR_x, "'Xt") \ + V(LDRB_w, "'Wt") \ + V(LDRH_w, "'Wt") \ + V(LDR_w, "'Wt") \ + V(LDR_x, "'Xt") \ + V(LDRSB_x, "'Xt") \ + V(LDRSH_x, "'Xt") \ + V(LDRSW_x, "'Xt") \ + V(LDRSB_w, "'Wt") \ + V(LDRSH_w, "'Wt") \ + V(STR_b, "'Bt") \ + V(STR_h, "'Ht") \ + V(STR_s, "'St") \ + V(STR_d, "'Dt") \ + V(LDR_b, "'Bt") \ + V(LDR_h, "'Ht") \ + V(LDR_s, "'St") \ + V(LDR_d, "'Dt") \ + V(STR_q, "'Qt") \ + V(LDR_q, "'Qt") void Disassembler::VisitLoadStorePreIndex(const Instruction *instr) { - const char *mnemonic = "unimplemented"; const char *form = "(LoadStorePreIndex)"; + const char *suffix = ", ['Xns'ILSi]!"; switch (instr->Mask(LoadStorePreIndexMask)) { -#define LS_PREINDEX(A, B, C) \ - case A##_pre: \ - mnemonic = B; \ - form = C ", ['Xns'ILSi]!"; \ +#define LS_PREINDEX(A, B) \ + case A##_pre: \ + form = B; \ break; LOAD_STORE_LIST(LS_PREINDEX) #undef LS_PREINDEX } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form, suffix); } void Disassembler::VisitLoadStorePostIndex(const Instruction *instr) { - const char *mnemonic = "unimplemented"; const char *form = "(LoadStorePostIndex)"; + const char *suffix = ", ['Xns]'ILSi"; switch (instr->Mask(LoadStorePostIndexMask)) { -#define LS_POSTINDEX(A, B, C) \ - case A##_post: \ - mnemonic = B; \ - form = C ", ['Xns]'ILSi"; \ +#define LS_POSTINDEX(A, B) \ + case A##_post: \ + form = B; \ break; LOAD_STORE_LIST(LS_POSTINDEX) #undef LS_POSTINDEX } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form, suffix); } void Disassembler::VisitLoadStoreUnsignedOffset(const Instruction *instr) { - const char *mnemonic = "unimplemented"; const char *form = "(LoadStoreUnsignedOffset)"; + const char *suffix = ", ['Xns'ILU]"; switch (instr->Mask(LoadStoreUnsignedOffsetMask)) { -#define LS_UNSIGNEDOFFSET(A, B, C) \ - case A##_unsigned: \ - mnemonic = B; \ - form = C ", ['Xns'ILU]"; \ +#define LS_UNSIGNEDOFFSET(A, B) \ + case A##_unsigned: \ + form = B; \ break; LOAD_STORE_LIST(LS_UNSIGNEDOFFSET) #undef LS_UNSIGNEDOFFSET case PRFM_unsigned: - mnemonic = "prfm"; - form = "'prefOp, ['Xns'ILU]"; + form = "'prefOp"; } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form, suffix); } void Disassembler::VisitLoadStoreRCpcUnscaledOffset(const Instruction *instr) { - const char *mnemonic; + const char *mnemonic = mnemonic_.c_str(); const char *form = "'Wt, ['Xns'ILS]"; const char *form_x = "'Xt, ['Xns'ILS]"; - switch (instr->Mask(LoadStoreRCpcUnscaledOffsetMask)) { - case STLURB: - mnemonic = "stlurb"; - break; - case LDAPURB: - mnemonic = "ldapurb"; - break; - case LDAPURSB_w: - mnemonic = "ldapursb"; - break; - case LDAPURSB_x: - mnemonic = "ldapursb"; - form = form_x; - break; - case STLURH: - mnemonic = "stlurh"; - break; - case LDAPURH: - mnemonic = "ldapurh"; - break; - case LDAPURSH_w: - mnemonic = "ldapursh"; - break; - case LDAPURSH_x: - mnemonic = "ldapursh"; - form = form_x; - break; - case STLUR_w: - mnemonic = "stlur"; - break; - case LDAPUR_w: - mnemonic = "ldapur"; - break; - case LDAPURSW: - mnemonic = "ldapursw"; - form = form_x; - break; - case STLUR_x: - mnemonic = "stlur"; - form = form_x; - break; - case LDAPUR_x: - mnemonic = "ldapur"; + switch (form_hash_) { + case "ldapursb_64_ldapstl_unscaled"_h: + case "ldapursh_64_ldapstl_unscaled"_h: + case "ldapursw_64_ldapstl_unscaled"_h: + case "ldapur_64_ldapstl_unscaled"_h: + case "stlur_64_ldapstl_unscaled"_h: form = form_x; break; - default: - mnemonic = "unimplemented"; - form = "(LoadStoreRCpcUnscaledOffset)"; } Format(instr, mnemonic, form); @@ -1657,22 +1613,20 @@ void Disassembler::VisitLoadStoreRCpcUnscaledOffset(const Instruction *instr) { void Disassembler::VisitLoadStoreRegisterOffset(const Instruction *instr) { - const char *mnemonic = "unimplemented"; const char *form = "(LoadStoreRegisterOffset)"; + const char *suffix = ", ['Xns, 'Offsetreg]"; switch (instr->Mask(LoadStoreRegisterOffsetMask)) { -#define LS_REGISTEROFFSET(A, B, C) \ - case A##_reg: \ - mnemonic = B; \ - form = C ", ['Xns, 'Offsetreg]"; \ +#define LS_REGISTEROFFSET(A, B) \ + case A##_reg: \ + form = B; \ break; LOAD_STORE_LIST(LS_REGISTEROFFSET) #undef LS_REGISTEROFFSET case PRFM_reg: - mnemonic = "prfm"; - form = "'prefOp, ['Xns, 'Offsetreg]"; + form = "'prefOp"; } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form, suffix); } @@ -1818,67 +1772,61 @@ void Disassembler::VisitLoadLiteral(const Instruction *instr) { } -#define LOAD_STORE_PAIR_LIST(V) \ - V(STP_w, "stp", "'Wt, 'Wt2", "2") \ - V(LDP_w, "ldp", "'Wt, 'Wt2", "2") \ - V(LDPSW_x, "ldpsw", "'Xt, 'Xt2", "2") \ - V(STP_x, "stp", "'Xt, 'Xt2", "3") \ - V(LDP_x, "ldp", "'Xt, 'Xt2", "3") \ - V(STP_s, "stp", "'St, 'St2", "2") \ - V(LDP_s, "ldp", "'St, 'St2", "2") \ - V(STP_d, "stp", "'Dt, 'Dt2", "3") \ - V(LDP_d, "ldp", "'Dt, 'Dt2", "3") \ - V(LDP_q, "ldp", "'Qt, 'Qt2", "4") \ - V(STP_q, "stp", "'Qt, 'Qt2", "4") +#define LOAD_STORE_PAIR_LIST(V) \ + V(STP_w, "'Wt, 'Wt2", "2") \ + V(LDP_w, "'Wt, 'Wt2", "2") \ + V(LDPSW_x, "'Xt, 'Xt2", "2") \ + V(STP_x, "'Xt, 'Xt2", "3") \ + V(LDP_x, "'Xt, 'Xt2", "3") \ + V(STP_s, "'St, 'St2", "2") \ + V(LDP_s, "'St, 'St2", "2") \ + V(STP_d, "'Dt, 'Dt2", "3") \ + V(LDP_d, "'Dt, 'Dt2", "3") \ + V(LDP_q, "'Qt, 'Qt2", "4") \ + V(STP_q, "'Qt, 'Qt2", "4") void Disassembler::VisitLoadStorePairPostIndex(const Instruction *instr) { - const char *mnemonic = "unimplemented"; const char *form = "(LoadStorePairPostIndex)"; switch (instr->Mask(LoadStorePairPostIndexMask)) { -#define LSP_POSTINDEX(A, B, C, D) \ +#define LSP_POSTINDEX(A, B, C) \ case A##_post: \ - mnemonic = B; \ - form = C ", ['Xns]'ILP" D "i"; \ + form = B ", ['Xns]'ILP" C "i"; \ break; LOAD_STORE_PAIR_LIST(LSP_POSTINDEX) #undef LSP_POSTINDEX } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form); } void Disassembler::VisitLoadStorePairPreIndex(const Instruction *instr) { - const char *mnemonic = "unimplemented"; const char *form = "(LoadStorePairPreIndex)"; switch (instr->Mask(LoadStorePairPreIndexMask)) { -#define LSP_PREINDEX(A, B, C, D) \ +#define LSP_PREINDEX(A, B, C) \ case A##_pre: \ - mnemonic = B; \ - form = C ", ['Xns'ILP" D "i]!"; \ + form = B ", ['Xns'ILP" C "i]!"; \ break; LOAD_STORE_PAIR_LIST(LSP_PREINDEX) #undef LSP_PREINDEX } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form); } void Disassembler::VisitLoadStorePairOffset(const Instruction *instr) { - const char *mnemonic = "unimplemented"; const char *form = "(LoadStorePairOffset)"; switch (instr->Mask(LoadStorePairOffsetMask)) { -#define LSP_OFFSET(A, B, C, D) \ +#define LSP_OFFSET(A, B, C) \ case A##_off: \ - mnemonic = B; \ - form = C ", ['Xns'ILP" D "]"; \ + form = B ", ['Xns'ILP" C "]"; \ break; LOAD_STORE_PAIR_LIST(LSP_OFFSET) #undef LSP_OFFSET } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form); } @@ -2038,29 +1986,15 @@ void Disassembler::VisitLoadStoreExclusive(const Instruction *instr) { } void Disassembler::VisitLoadStorePAC(const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "(LoadStorePAC)"; - - switch (instr->Mask(LoadStorePACMask)) { - case LDRAA: - mnemonic = "ldraa"; - form = "'Xt, ['Xns'ILA]"; - break; - case LDRAB: - mnemonic = "ldrab"; - form = "'Xt, ['Xns'ILA]"; - break; - case LDRAA_pre: - mnemonic = "ldraa"; - form = "'Xt, ['Xns'ILA]!"; - break; - case LDRAB_pre: - mnemonic = "ldrab"; - form = "'Xt, ['Xns'ILA]!"; + const char *form = "'Xt, ['Xns'ILA]"; + const char *suffix = ""; + switch (form_hash_) { + case "ldraa_64w_ldst_pac"_h: + case "ldrab_64w_ldst_pac"_h: + suffix = "!"; break; } - - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form, suffix); } #define ATOMIC_MEMORY_SIMPLE_LIST(V) \ @@ -2211,35 +2145,17 @@ void Disassembler::VisitAtomicMemory(const Instruction *instr) { void Disassembler::VisitFPCompare(const Instruction *instr) { - const char *mnemonic = "unimplemented"; const char *form = "'Fn, 'Fm"; - const char *form_zero = "'Fn, #0.0"; - - switch (instr->Mask(FPCompareMask)) { - case FCMP_h_zero: - case FCMP_s_zero: - case FCMP_d_zero: - form = form_zero; - VIXL_FALLTHROUGH(); - case FCMP_h: - case FCMP_s: - case FCMP_d: - mnemonic = "fcmp"; - break; - case FCMPE_h_zero: - case FCMPE_s_zero: - case FCMPE_d_zero: - form = form_zero; - VIXL_FALLTHROUGH(); - case FCMPE_h: - case FCMPE_s: - case FCMPE_d: - mnemonic = "fcmpe"; - break; - default: - form = "(FPCompare)"; + switch (form_hash_) { + case "fcmpe_dz_floatcmp"_h: + case "fcmpe_hz_floatcmp"_h: + case "fcmpe_sz_floatcmp"_h: + case "fcmp_dz_floatcmp"_h: + case "fcmp_hz_floatcmp"_h: + case "fcmp_sz_floatcmp"_h: + form = "'Fn, #0.0"; } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form); } @@ -2328,25 +2244,17 @@ void Disassembler::VisitFPDataProcessing3Source(const Instruction *instr) { void Disassembler::VisitFPImmediate(const Instruction *instr) { - const char *mnemonic = ""; - const char *form = "(FPImmediate)"; - switch (instr->Mask(FPImmediateMask)) { - case FMOV_h_imm: - mnemonic = "fmov"; - form = "'Hd, 'IFP"; - break; - case FMOV_s_imm: - mnemonic = "fmov"; - form = "'Sd, 'IFP"; + const char *form = "'Hd"; + const char *suffix = ", 'IFP"; + switch (form_hash_) { + case "fmov_s_floatimm"_h: + form = "'Sd"; break; - case FMOV_d_imm: - mnemonic = "fmov"; - form = "'Dd, 'IFP"; + case "fmov_d_floatimm"_h: + form = "'Dd"; break; - default: - VIXL_UNREACHABLE(); } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form, suffix); } @@ -4402,31 +4310,21 @@ void Disassembler::VisitSVE64BitGatherLoad_VectorPlusImm( void Disassembler::VisitSVE64BitGatherPrefetch_ScalarPlus64BitScaledOffsets( const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "(SVE64BitGatherPrefetch_ScalarPlus64BitScaledOffsets)"; + const char *form = "'prefSVEOp, 'Pgl, ['Xns, 'Zm.d"; + const char *suffix = "]"; - switch ( - instr->Mask(SVE64BitGatherPrefetch_ScalarPlus64BitScaledOffsetsMask)) { - case PRFB_i_p_bz_d_64_scaled: - mnemonic = "prfb"; - form = "'prefSVEOp, 'Pgl, ['Xns, 'Zm.d]"; - break; - case PRFD_i_p_bz_d_64_scaled: - mnemonic = "prfd"; - form = "'prefSVEOp, 'Pgl, ['Xns, 'Zm.d, lsl #3]"; - break; - case PRFH_i_p_bz_d_64_scaled: - mnemonic = "prfh"; - form = "'prefSVEOp, 'Pgl, ['Xns, 'Zm.d, lsl #1]"; + switch (form_hash_) { + case "prfh_i_p_bz_d_64_scaled"_h: + suffix = ", lsl #1]"; break; - case PRFW_i_p_bz_d_64_scaled: - mnemonic = "prfw"; - form = "'prefSVEOp, 'Pgl, ['Xns, 'Zm.d, lsl #2]"; + case "prfs_i_p_bz_d_64_scaled"_h: + suffix = ", lsl #2]"; break; - default: + case "prfd_i_p_bz_d_64_scaled"_h: + suffix = ", lsl #3]"; break; } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form, suffix); } void Disassembler:: @@ -4463,28 +4361,11 @@ void Disassembler:: void Disassembler::VisitSVE64BitGatherPrefetch_VectorPlusImm( const Instruction *instr) { - const char *mnemonic = "unimplemented"; const char *form = (instr->ExtractBits(20, 16) != 0) ? "'prefSVEOp, 'Pgl, ['Zn.d, #'u2016]" : "'prefSVEOp, 'Pgl, ['Zn.d]"; - switch (instr->Mask(SVE64BitGatherPrefetch_VectorPlusImmMask)) { - case PRFB_i_p_ai_d: - mnemonic = "prfb"; - break; - case PRFD_i_p_ai_d: - mnemonic = "prfd"; - break; - case PRFH_i_p_ai_d: - mnemonic = "prfh"; - break; - case PRFW_i_p_ai_d: - mnemonic = "prfw"; - break; - default: - break; - } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form); } void Disassembler::VisitSVE64BitScatterStore_ScalarPlus64BitScaledOffsets( @@ -4582,29 +4463,12 @@ void Disassembler::VisitSVE64BitScatterStore_VectorPlusImm( void Disassembler::VisitSVEBitwiseLogicalWithImm_Unpredicated( const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "'Zd.'tl, 'Zd.'tl, 'ITriSvel"; - if (instr->GetSVEImmLogical() == 0) { // The immediate encoded in the instruction is not in the expected format. Format(instr, "unallocated", "(SVEBitwiseImm)"); - return; - } - - switch (instr->Mask(SVEBitwiseLogicalWithImm_UnpredicatedMask)) { - case AND_z_zi: - mnemonic = "and"; - break; - case EOR_z_zi: - mnemonic = "eor"; - break; - case ORR_z_zi: - mnemonic = "orr"; - break; - default: - break; + } else { + FormatWithDecodedMnemonic(instr, "'Zd.'tl, 'Zd.'tl, 'ITriSvel"); } - Format(instr, mnemonic, form); } void Disassembler::VisitSVEBitwiseLogical_Predicated(const Instruction *instr) { @@ -4652,28 +4516,11 @@ void Disassembler::VisitSVEBitwiseShiftByVector_Predicated( void Disassembler::VisitSVEBitwiseShiftByWideElements_Predicated( const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "'Zd.'t, 'Pgl/m, 'Zd.'t, 'Zn.d"; - if (instr->GetSVESize() == kDRegSizeInBytesLog2) { - form = "(SVEBitwiseShiftByWideElements_Predicated)"; + Format(instr, "unallocated", "(SVEBitwiseShiftByWideElements_Predicated)"); } else { - switch (instr->Mask(SVEBitwiseShiftByWideElements_PredicatedMask)) { - case ASR_z_p_zw: - mnemonic = "asr"; - break; - case LSL_z_p_zw: - mnemonic = "lsl"; - break; - case LSR_z_p_zw: - mnemonic = "lsr"; - break; - default: - form = "(SVEBitwiseShiftByWideElements_Predicated)"; - break; - } + FormatWithDecodedMnemonic(instr, "'Zd.'t, 'Pgl/m, 'Zd.'t, 'Zn.d"); } - Format(instr, mnemonic, form); } static bool SVEMoveMaskPreferred(uint64_t value, int lane_bytes_log2) { @@ -4884,24 +4731,12 @@ void Disassembler::VisitSVEConditionallyBroadcastElementToVector( void Disassembler::VisitSVEConditionallyExtractElementToGeneralRegister( const Instruction *instr) { - const char *mnemonic = "unimplemented"; const char *form = "'Wd, 'Pgl, 'Wd, 'Zn.'t"; if (instr->GetSVESize() == kDRegSizeInBytesLog2) { form = "'Xd, p'u1210, 'Xd, 'Zn.'t"; } - - switch (instr->Mask(SVEConditionallyExtractElementToGeneralRegisterMask)) { - case CLASTA_r_p_z: - mnemonic = "clasta"; - break; - case CLASTB_r_p_z: - mnemonic = "clastb"; - break; - default: - break; - } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form); } void Disassembler::VisitSVEConditionallyExtractElementToSIMDFPScalar( @@ -4985,61 +4820,38 @@ void Disassembler::VisitSVEContiguousNonFaultLoad_ScalarPlusImm( void Disassembler::VisitSVEContiguousNonTemporalLoad_ScalarPlusImm( const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "(SVEContiguousNonTemporalLoad_ScalarPlusImm)"; - + const char *form = "{'Zt.b}, 'Pgl/z, ['Xns"; const char *suffix = (instr->ExtractBits(19, 16) == 0) ? "]" : ", #'s1916, mul vl]"; - switch (instr->Mask(SVEContiguousNonTemporalLoad_ScalarPlusImmMask)) { - case LDNT1B_z_p_bi_contiguous: - mnemonic = "ldnt1b"; - form = "{'Zt.b}, 'Pgl/z, ['Xns"; - break; - case LDNT1D_z_p_bi_contiguous: - mnemonic = "ldnt1d"; + switch (form_hash_) { + case "ldnt1d_z_p_bi_contiguous"_h: form = "{'Zt.d}, 'Pgl/z, ['Xns"; break; - case LDNT1H_z_p_bi_contiguous: - mnemonic = "ldnt1h"; + case "ldnt1h_z_p_bi_contiguous"_h: form = "{'Zt.h}, 'Pgl/z, ['Xns"; break; - case LDNT1W_z_p_bi_contiguous: - mnemonic = "ldnt1w"; + case "ldnt1w_z_p_bi_contiguous"_h: form = "{'Zt.s}, 'Pgl/z, ['Xns"; break; - default: - suffix = NULL; - break; } - Format(instr, mnemonic, form, suffix); + FormatWithDecodedMnemonic(instr, form, suffix); } void Disassembler::VisitSVEContiguousNonTemporalLoad_ScalarPlusScalar( const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "(SVEContiguousNonTemporalLoad_ScalarPlusScalar)"; - - switch (instr->Mask(SVEContiguousNonTemporalLoad_ScalarPlusScalarMask)) { - case LDNT1B_z_p_br_contiguous: - mnemonic = "ldnt1b"; - form = "{'Zt.b}, 'Pgl/z, ['Xns, 'Rm]"; - break; - case LDNT1D_z_p_br_contiguous: - mnemonic = "ldnt1d"; + const char *form = "{'Zt.b}, 'Pgl/z, ['Xns, 'Rm]"; + switch (form_hash_) { + case "ldnt1d_z_p_br_contiguous"_h: form = "{'Zt.d}, 'Pgl/z, ['Xns, 'Rm, lsl #3]"; break; - case LDNT1H_z_p_br_contiguous: - mnemonic = "ldnt1h"; + case "ldnt1h_z_p_br_contiguous"_h: form = "{'Zt.h}, 'Pgl/z, ['Xns, 'Rm, lsl #1]"; break; - case LDNT1W_z_p_br_contiguous: - mnemonic = "ldnt1w"; + case "ldnt1w_z_p_br_contiguous"_h: form = "{'Zt.s}, 'Pgl/z, ['Xns, 'Rm, lsl #2]"; break; - default: - break; } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form); } void Disassembler::VisitSVEContiguousNonTemporalStore_ScalarPlusImm( @@ -5141,31 +4953,12 @@ void Disassembler::VisitSVEContiguousPrefetch_ScalarPlusScalar( void Disassembler::VisitSVEContiguousStore_ScalarPlusImm( const Instruction *instr) { - const char *mnemonic = "unimplemented"; - // The 'size' field isn't in the usual place here. const char *form = "{'Zt.'tls}, 'Pgl, ['Xns, #'s1916, mul vl]"; if (instr->ExtractBits(19, 16) == 0) { form = "{'Zt.'tls}, 'Pgl, ['Xns]"; } - - switch (instr->Mask(SVEContiguousStore_ScalarPlusImmMask)) { - case ST1B_z_p_bi: - mnemonic = "st1b"; - break; - case ST1D_z_p_bi: - mnemonic = "st1d"; - break; - case ST1H_z_p_bi: - mnemonic = "st1h"; - break; - case ST1W_z_p_bi: - mnemonic = "st1w"; - break; - default: - break; - } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form); } void Disassembler::VisitSVEContiguousStore_ScalarPlusScalar( @@ -5250,24 +5043,11 @@ void Disassembler::VisitSVECopySIMDFPScalarRegisterToVector_Predicated( void Disassembler::VisitSVEExtractElementToGeneralRegister( const Instruction *instr) { - const char *mnemonic = "unimplemented"; const char *form = "'Wd, 'Pgl, 'Zn.'t"; - if (instr->GetSVESize() == kDRegSizeInBytesLog2) { form = "'Xd, p'u1210, 'Zn.'t"; } - - switch (instr->Mask(SVEExtractElementToGeneralRegisterMask)) { - case LASTA_r_p_z: - mnemonic = "lasta"; - break; - case LASTB_r_p_z: - mnemonic = "lastb"; - break; - default: - break; - } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form); } void Disassembler::VisitSVEExtractElementToSIMDFPScalarRegister( @@ -5444,22 +5224,13 @@ void Disassembler::VisitSVEFPConvertToInt(const Instruction *instr) { } void Disassembler::VisitSVEFPExponentialAccelerator(const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "(SVEFPExponentialAccelerator)"; - unsigned size = instr->GetSVESize(); - switch (instr->Mask(SVEFPExponentialAcceleratorMask)) { - case FEXPA_z_z: - if ((size == kHRegSizeInBytesLog2) || (size == kSRegSizeInBytesLog2) || - (size == kDRegSizeInBytesLog2)) { - mnemonic = "fexpa"; - form = "'Zd.'t, 'Zn.'t"; - } - break; - default: - break; + if ((size == kHRegSizeInBytesLog2) || (size == kSRegSizeInBytesLog2) || + (size == kDRegSizeInBytesLog2)) { + FormatWithDecodedMnemonic(instr, "'Zd.'t, 'Zn.'t"); + } else { + VisitUnallocated(instr); } - Format(instr, mnemonic, form); } void Disassembler::VisitSVEFPRoundToIntegralValue(const Instruction *instr) { @@ -5471,41 +5242,23 @@ void Disassembler::VisitSVEFPRoundToIntegralValue(const Instruction *instr) { } void Disassembler::VisitSVEFPTrigMulAddCoefficient(const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "(SVEFPTrigMulAddCoefficient)"; - unsigned size = instr->GetSVESize(); - switch (instr->Mask(SVEFPTrigMulAddCoefficientMask)) { - case FTMAD_z_zzi: - if ((size == kHRegSizeInBytesLog2) || (size == kSRegSizeInBytesLog2) || - (size == kDRegSizeInBytesLog2)) { - mnemonic = "ftmad"; - form = "'Zd.'t, 'Zd.'t, 'Zn.'t, #'u1816"; - } - break; - default: - break; + if ((size == kHRegSizeInBytesLog2) || (size == kSRegSizeInBytesLog2) || + (size == kDRegSizeInBytesLog2)) { + FormatWithDecodedMnemonic(instr, "'Zd.'t, 'Zd.'t, 'Zn.'t, #'u1816"); + } else { + VisitUnallocated(instr); } - Format(instr, mnemonic, form); } void Disassembler::VisitSVEFPTrigSelectCoefficient(const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "(SVEFPTrigSelectCoefficient)"; - unsigned size = instr->GetSVESize(); - switch (instr->Mask(SVEFPTrigSelectCoefficientMask)) { - case FTSSEL_z_zz: - if ((size == kHRegSizeInBytesLog2) || (size == kSRegSizeInBytesLog2) || - (size == kDRegSizeInBytesLog2)) { - mnemonic = "ftssel"; - form = "'Zd.'t, 'Zn.'t, 'Zm.'t"; - } - break; - default: - break; + if ((size == kHRegSizeInBytesLog2) || (size == kSRegSizeInBytesLog2) || + (size == kDRegSizeInBytesLog2)) { + FormatWithDecodedMnemonic(instr, "'Zd.'t, 'Zn.'t, 'Zm.'t"); + } else { + VisitUnallocated(instr); } - Format(instr, mnemonic, form); } void Disassembler::VisitSVEFPUnaryOp(const Instruction *instr) { @@ -5541,36 +5294,11 @@ void Disassembler::VisitSVEIncDecRegisterByElementCount( void Disassembler::VisitSVEIncDecVectorByElementCount( const Instruction *instr) { - const char *mnemonic = "unimplemented"; const char *form = IncDecFormHelper(instr, "'Zd.'t, 'Ipc, mul #'u1916+1", "'Zd.'t, 'Ipc", "'Zd.'t"); - - switch (instr->Mask(SVEIncDecVectorByElementCountMask)) { - case DECD_z_zs: - mnemonic = "decd"; - break; - case DECH_z_zs: - mnemonic = "dech"; - break; - case DECW_z_zs: - mnemonic = "decw"; - break; - case INCD_z_zs: - mnemonic = "incd"; - break; - case INCH_z_zs: - mnemonic = "inch"; - break; - case INCW_z_zs: - mnemonic = "incw"; - break; - default: - form = "(SVEIncDecVectorByElementCount)"; - break; - } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form); } void Disassembler::VisitSVEInsertGeneralRegister(const Instruction *instr) { @@ -5675,49 +5403,12 @@ void Disassembler::VisitSVEIntConvertToFP(const Instruction *instr) { void Disassembler::VisitSVEIntDivideVectors_Predicated( const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "'Zd.'t, 'Pgl/m, 'Zd.'t, 'Zn.'t"; - - switch (instr->Mask(SVEIntDivideVectors_PredicatedMask)) { - case SDIVR_z_p_zz: - mnemonic = "sdivr"; - break; - case SDIV_z_p_zz: - mnemonic = "sdiv"; - break; - case UDIVR_z_p_zz: - mnemonic = "udivr"; - break; - case UDIV_z_p_zz: - mnemonic = "udiv"; - break; - default: - break; - } - - switch (instr->Mask(SVEIntDivideVectors_PredicatedMask)) { - case SDIVR_z_p_zz: - case SDIV_z_p_zz: - case UDIVR_z_p_zz: - case UDIV_z_p_zz: - switch (instr->GetSVESize()) { - case kBRegSizeInBytesLog2: - case kHRegSizeInBytesLog2: - mnemonic = "unimplemented"; - form = "(SVEIntBinaryArithmeticPredicated)"; - break; - case kSRegSizeInBytesLog2: - case kDRegSizeInBytesLog2: - // The default form works for these instructions. - break; - default: - // GetSVESize() should never return other values. - VIXL_UNREACHABLE(); - break; - } + unsigned size = instr->GetSVESize(); + if ((size == kSRegSizeInBytesLog2) || (size == kDRegSizeInBytesLog2)) { + FormatWithDecodedMnemonic(instr, "'Zd.'t, 'Pgl/m, 'Zd.'t, 'Zn.'t"); + } else { + VisitUnallocated(instr); } - - Format(instr, mnemonic, form); } void Disassembler::VisitSVEIntMinMaxDifference_Predicated( @@ -5726,28 +5417,16 @@ void Disassembler::VisitSVEIntMinMaxDifference_Predicated( } void Disassembler::VisitSVEIntMinMaxImm_Unpredicated(const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "'Zd.'t, 'Zd.'t, #'u1205"; + const char *form = "'Zd.'t, 'Zd.'t, #"; + const char *suffix = "'u1205"; - switch (instr->Mask(SVEIntMinMaxImm_UnpredicatedMask)) { - case SMAX_z_zi: - mnemonic = "smax"; - form = "'Zd.'t, 'Zd.'t, #'s1205"; - break; - case SMIN_z_zi: - mnemonic = "smin"; - form = "'Zd.'t, 'Zd.'t, #'s1205"; - break; - case UMAX_z_zi: - mnemonic = "umax"; - break; - case UMIN_z_zi: - mnemonic = "umin"; - break; - default: + switch (form_hash_) { + case "smax_z_zi"_h: + case "smin_z_zi"_h: + suffix = "'s1205"; break; } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form, suffix); } void Disassembler::VisitSVEIntMulImm_Unpredicated(const Instruction *instr) { @@ -5862,35 +5541,24 @@ void Disassembler::VisitSVELoadAndBroadcastElement(const Instruction *instr) { void Disassembler::VisitSVELoadAndBroadcastQOWord_ScalarPlusImm( const Instruction *instr) { - const char *mnemonic = mnemonic_.c_str(); const char *form = "{'Zt.'tmsz}, 'Pgl/z, ['Xns"; const char *suffix = ", #'s1916*16]"; switch (form_hash_) { - case "ld1rqb_z_p_bi_u8"_h: - case "ld1rqd_z_p_bi_u64"_h: - case "ld1rqh_z_p_bi_u16"_h: - case "ld1rqw_z_p_bi_u32"_h: - // Nothing to do. - break; case "ld1rob_z_p_bi_u8"_h: case "ld1rod_z_p_bi_u64"_h: case "ld1roh_z_p_bi_u16"_h: case "ld1row_z_p_bi_u32"_h: suffix = ", #'s1916*32]"; break; - default: - VIXL_UNREACHABLE(); - break; } if (instr->ExtractBits(19, 16) == 0) suffix = "]"; - Format(instr, mnemonic, form, suffix); + FormatWithDecodedMnemonic(instr, form, suffix); } void Disassembler::VisitSVELoadAndBroadcastQOWord_ScalarPlusScalar( const Instruction *instr) { - const char *mnemonic = mnemonic_.c_str(); const char *form = "{'Zt.'tmsz}, 'Pgl/z, ['Xns, "; const char *suffix = "'Rm, lsl #'u2423]"; @@ -5899,19 +5567,8 @@ void Disassembler::VisitSVELoadAndBroadcastQOWord_ScalarPlusScalar( case "ld1rob_z_p_br_contiguous"_h: suffix = "'Rm]"; break; - case "ld1rqd_z_p_br_contiguous"_h: - case "ld1rod_z_p_br_contiguous"_h: - case "ld1rqh_z_p_br_contiguous"_h: - case "ld1roh_z_p_br_contiguous"_h: - case "ld1rqw_z_p_br_contiguous"_h: - case "ld1row_z_p_br_contiguous"_h: - // Nothing to do. - break; - default: - VIXL_UNREACHABLE(); - break; } - Format(instr, mnemonic, form, suffix); + FormatWithDecodedMnemonic(instr, form, suffix); } void Disassembler::VisitSVELoadMultipleStructures_ScalarPlusImm( @@ -6248,54 +5905,11 @@ void Disassembler::VisitSVESaturatingIncDecRegisterByElementCount( void Disassembler::VisitSVESaturatingIncDecVectorByElementCount( const Instruction *instr) { - const char *mnemonic = "unimplemented"; const char *form = IncDecFormHelper(instr, "'Zd.'t, 'Ipc, mul #'u1916+1", "'Zd.'t, 'Ipc", "'Zd.'t"); - - switch (instr->Mask(SVESaturatingIncDecVectorByElementCountMask)) { - case SQDECD_z_zs: - mnemonic = "sqdecd"; - break; - case SQDECH_z_zs: - mnemonic = "sqdech"; - break; - case SQDECW_z_zs: - mnemonic = "sqdecw"; - break; - case SQINCD_z_zs: - mnemonic = "sqincd"; - break; - case SQINCH_z_zs: - mnemonic = "sqinch"; - break; - case SQINCW_z_zs: - mnemonic = "sqincw"; - break; - case UQDECD_z_zs: - mnemonic = "uqdecd"; - break; - case UQDECH_z_zs: - mnemonic = "uqdech"; - break; - case UQDECW_z_zs: - mnemonic = "uqdecw"; - break; - case UQINCD_z_zs: - mnemonic = "uqincd"; - break; - case UQINCH_z_zs: - mnemonic = "uqinch"; - break; - case UQINCW_z_zs: - mnemonic = "uqincw"; - break; - default: - form = "(SVEElementCount)"; - break; - } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form); } void Disassembler::VisitSVEStoreMultipleStructures_ScalarPlusImm( @@ -6457,32 +6071,12 @@ void Disassembler::VisitSVEUnpackPredicateElements(const Instruction *instr) { } void Disassembler::VisitSVEUnpackVectorElements(const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "'Zd.'t, 'Zn.'th"; - if (instr->GetSVESize() == 0) { // The lowest lane size of the destination vector is H-sized lane. - Format(instr, "unallocated", "(SVEUnpackVectorElements)"); - return; - } - - switch (instr->Mask(SVEUnpackVectorElementsMask)) { - case SUNPKHI_z_z: - mnemonic = "sunpkhi"; - break; - case SUNPKLO_z_z: - mnemonic = "sunpklo"; - break; - case UUNPKHI_z_z: - mnemonic = "uunpkhi"; - break; - case UUNPKLO_z_z: - mnemonic = "uunpklo"; - break; - default: - break; + VisitUnallocated(instr); + } else { + FormatWithDecodedMnemonic(instr, "'Zd.'t, 'Zn.'th"); } - Format(instr, mnemonic, form); } void Disassembler::VisitSVEVectorSplice(const Instruction *instr) { @@ -6632,68 +6226,33 @@ void Disassembler::VisitSVEFPCompareWithZero(const Instruction *instr) { } void Disassembler::VisitSVEFPComplexAddition(const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "(SVEFPComplexAddition)"; - - if (instr->GetSVEVectorFormat() != kFormatVnB) { - switch (instr->Mask(SVEFPComplexAdditionMask)) { - case FCADD_z_p_zz: - mnemonic = "fcadd"; - if (instr->ExtractBit(16) == 0) { - form = "'Zd.'t, 'Pgl/m, 'Zd.'t, 'Zn.'t, #90"; - } else { - form = "'Zd.'t, 'Pgl/m, 'Zd.'t, 'Zn.'t, #270"; - } - break; - default: - break; - } + // Bit 15 is always set, so this gives 90 * 1 or 3. + const char *form = "'Zd.'t, 'Pgl/m, 'Zd.'t, 'Zn.'t, #'u1615*90"; + if (instr->GetSVEVectorFormat() == kFormatVnB) { + VisitUnallocated(instr); + } else { + FormatWithDecodedMnemonic(instr, form); } - Format(instr, mnemonic, form); } void Disassembler::VisitSVEFPComplexMulAdd(const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "(SVEFPComplexMulAdd)"; - const char *suffix = NULL; - - const char *fcmla_constants[] = {"0", "90", "180", "270"}; - - if (instr->GetSVEVectorFormat() != kFormatVnB) { - switch (instr->Mask(SVEFPComplexMulAddMask)) { - case FCMLA_z_p_zzz: - mnemonic = "fcmla"; - form = "'Zd.'t, 'Pgl/m, 'Zn.'t, 'Zm.'t, #"; - suffix = fcmla_constants[instr->ExtractBits(14, 13)]; - break; - default: - break; - } + const char *form = "'Zd.'t, 'Pgl/m, 'Zn.'t, 'Zm.'t, #'u1413*90"; + if (instr->GetSVEVectorFormat() == kFormatVnB) { + VisitUnallocated(instr); + } else { + FormatWithDecodedMnemonic(instr, form); } - Format(instr, mnemonic, form, suffix); } void Disassembler::VisitSVEFPComplexMulAddIndex(const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "(SVEFPComplexMulAddIndex)"; - - const char *fcmla_constants[] = {"0", "90", "180", "270"}; - const char *suffix = fcmla_constants[instr->ExtractBits(11, 10)]; - - switch (instr->Mask(SVEFPComplexMulAddIndexMask)) { - case FCMLA_z_zzzi_h: - mnemonic = "fcmla"; - form = "'Zd.h, 'Zn.h, z'u1816.h['u2019], #"; - break; - case FCMLA_z_zzzi_s: - mnemonic = "fcmla"; - form = "'Zd.s, 'Zn.s, z'u1916.s['u2020], #"; - break; - default: - suffix = NULL; + const char *form = "'Zd.h, 'Zn.h, z'u1816.h['u2019]"; + const char *suffix = ", #'u1110*90"; + switch (form_hash_) { + case "fcmla_z_zzzi_s"_h: + form = "'Zd.s, 'Zn.s, z'u1916.s['u2020]"; break; } - Format(instr, mnemonic, form, suffix); + FormatWithDecodedMnemonic(instr, form, suffix); } void Disassembler::VisitSVEFPFastReduction(const Instruction *instr) { @@ -6705,27 +6264,16 @@ void Disassembler::VisitSVEFPFastReduction(const Instruction *instr) { } void Disassembler::VisitSVEFPMulIndex(const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "(SVEFPMulIndex)"; - - switch (instr->Mask(SVEFPMulIndexMask)) { - case FMUL_z_zzi_d: - mnemonic = "fmul"; + const char *form = "'Zd.h, 'Zn.h, z'u1816.h['u2222:2019]"; + switch (form_hash_) { + case "fmul_z_zzi_d"_h: form = "'Zd.d, 'Zn.d, z'u1916.d['u2020]"; break; - case FMUL_z_zzi_h: - case FMUL_z_zzi_h_i3h: - mnemonic = "fmul"; - form = "'Zd.h, 'Zn.h, z'u1816.h['u2222:2019]"; - break; - case FMUL_z_zzi_s: - mnemonic = "fmul"; + case "fmul_z_zzi_s"_h: form = "'Zd.s, 'Zn.s, z'u1816.s['u2019]"; break; - default: - break; } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form); } void Disassembler::VisitSVEFPMulAdd(const Instruction *instr) { @@ -6737,41 +6285,18 @@ void Disassembler::VisitSVEFPMulAdd(const Instruction *instr) { } void Disassembler::VisitSVEFPMulAddIndex(const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "(SVEFPMulAddIndex)"; - - switch (instr->Mask(SVEFPMulAddIndexMask)) { - case FMLA_z_zzzi_d: - mnemonic = "fmla"; - form = "'Zd.d, 'Zn.d, z'u1916.d['u2020]"; - break; - case FMLA_z_zzzi_s: - mnemonic = "fmla"; + const char *form = "'Zd.h, 'Zn.h, z'u1816.h['u2222:2019]"; + switch (form_hash_) { + case "fmla_z_zzzi_s"_h: + case "fmls_z_zzzi_s"_h: form = "'Zd.s, 'Zn.s, z'u1816.s['u2019]"; break; - case FMLS_z_zzzi_d: - mnemonic = "fmls"; + case "fmla_z_zzzi_d"_h: + case "fmls_z_zzzi_d"_h: form = "'Zd.d, 'Zn.d, z'u1916.d['u2020]"; break; - case FMLS_z_zzzi_s: - mnemonic = "fmls"; - form = "'Zd.s, 'Zn.s, z'u1816.s['u2019]"; - break; - case FMLA_z_zzzi_h: - case FMLA_z_zzzi_h_i3h: - mnemonic = "fmla"; - form = "'Zd.h, 'Zn.h, z'u1816.h['u2222:2019]"; - break; - case FMLS_z_zzzi_h: - case FMLS_z_zzzi_h_i3h: - mnemonic = "fmls"; - form = "'Zd.h, 'Zn.h, z'u1816.h['u2222:2019]"; - break; - default: - break; } - - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form); } void Disassembler::VisitSVEFPUnaryOpUnpredicated(const Instruction *instr) { @@ -6858,33 +6383,22 @@ void Disassembler::VisitSVEIncDecByPredicateCount(const Instruction *instr) { } void Disassembler::VisitSVEIndexGeneration(const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "(SVEIndexGeneration)"; - + const char *form = "'Zd.'t, #'s0905, #'s2016"; bool w_inputs = static_cast<unsigned>(instr->GetSVESize()) <= kWRegSizeInBytesLog2; - switch (instr->Mask(SVEIndexGenerationMask)) { - case INDEX_z_ii: - mnemonic = "index"; - form = "'Zd.'t, #'s0905, #'s2016"; - break; - case INDEX_z_ir: - mnemonic = "index"; + switch (form_hash_) { + case "index_z_ir"_h: form = w_inputs ? "'Zd.'t, #'s0905, 'Wm" : "'Zd.'t, #'s0905, 'Xm"; break; - case INDEX_z_ri: - mnemonic = "index"; + case "index_z_ri"_h: form = w_inputs ? "'Zd.'t, 'Wn, #'s2016" : "'Zd.'t, 'Xn, #'s2016"; break; - case INDEX_z_rr: - mnemonic = "index"; + case "index_z_rr"_h: form = w_inputs ? "'Zd.'t, 'Wn, 'Wm" : "'Zd.'t, 'Xn, 'Xm"; break; - default: - break; } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form); } void Disassembler::VisitSVEIntArithmeticUnpredicated(const Instruction *instr) { @@ -6900,95 +6414,31 @@ void Disassembler::VisitSVEIntCompareUnsignedImm(const Instruction *instr) { } void Disassembler::VisitSVEIntCompareVectors(const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "'Pd.'t, 'Pgl/z, 'Zn.'t, 'Zm.d"; - - switch (instr->Mask(SVEIntCompareVectorsMask)) { - case CMPEQ_p_p_zw: - mnemonic = "cmpeq"; - break; - case CMPEQ_p_p_zz: - mnemonic = "cmpeq"; - form = "'Pd.'t, 'Pgl/z, 'Zn.'t, 'Zm.'t"; - break; - case CMPGE_p_p_zw: - mnemonic = "cmpge"; - break; - case CMPGE_p_p_zz: - mnemonic = "cmpge"; - form = "'Pd.'t, 'Pgl/z, 'Zn.'t, 'Zm.'t"; - break; - case CMPGT_p_p_zw: - mnemonic = "cmpgt"; - break; - case CMPGT_p_p_zz: - mnemonic = "cmpgt"; - form = "'Pd.'t, 'Pgl/z, 'Zn.'t, 'Zm.'t"; - break; - case CMPHI_p_p_zw: - mnemonic = "cmphi"; - break; - case CMPHI_p_p_zz: - mnemonic = "cmphi"; - form = "'Pd.'t, 'Pgl/z, 'Zn.'t, 'Zm.'t"; - break; - case CMPHS_p_p_zw: - mnemonic = "cmphs"; - break; - case CMPHS_p_p_zz: - mnemonic = "cmphs"; - form = "'Pd.'t, 'Pgl/z, 'Zn.'t, 'Zm.'t"; - break; - case CMPLE_p_p_zw: - mnemonic = "cmple"; - break; - case CMPLO_p_p_zw: - mnemonic = "cmplo"; - break; - case CMPLS_p_p_zw: - mnemonic = "cmpls"; - break; - case CMPLT_p_p_zw: - mnemonic = "cmplt"; - break; - case CMPNE_p_p_zw: - mnemonic = "cmpne"; - break; - case CMPNE_p_p_zz: - mnemonic = "cmpne"; - form = "'Pd.'t, 'Pgl/z, 'Zn.'t, 'Zm.'t"; - break; - default: + const char *form = "'Pd.'t, 'Pgl/z, 'Zn.'t, 'Zm."; + const char *suffix = "d"; + switch (form_hash_) { + case "cmpeq_p_p_zz"_h: + case "cmpge_p_p_zz"_h: + case "cmpgt_p_p_zz"_h: + case "cmphi_p_p_zz"_h: + case "cmphs_p_p_zz"_h: + case "cmpne_p_p_zz"_h: + suffix = "'t"; break; } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form, suffix); } void Disassembler::VisitSVEIntMulAddPredicated(const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "(SVEIntMulAddPredicated)"; - - switch (instr->Mask(SVEIntMulAddPredicatedMask)) { - case MAD_z_p_zzz: - mnemonic = "mad"; - form = "'Zd.'t, 'Pgl/m, 'Zm.'t, 'Zn.'t"; - break; - case MLA_z_p_zzz: - mnemonic = "mla"; - form = "'Zd.'t, 'Pgl/m, 'Zn.'t, 'Zm.'t"; - break; - case MLS_z_p_zzz: - mnemonic = "mls"; - form = "'Zd.'t, 'Pgl/m, 'Zn.'t, 'Zm.'t"; - break; - case MSB_z_p_zzz: - mnemonic = "msb"; - form = "'Zd.'t, 'Pgl/m, 'Zm.'t, 'Zn.'t"; - break; - default: + const char *form = "'Zd.'t, 'Pgl/m, "; + const char *suffix = "'Zn.'t, 'Zm.'t"; + switch (form_hash_) { + case "mad_z_p_zzz"_h: + case "msb_z_p_zzz"_h: + suffix = "'Zm.'t, 'Zn.'t"; break; } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form, suffix); } void Disassembler::VisitSVEIntMulAddUnpredicated(const Instruction *instr) { @@ -7004,50 +6454,14 @@ void Disassembler::VisitSVEMovprfx(const Instruction *instr) { } void Disassembler::VisitSVEIntReduction(const Instruction *instr) { - const char *mnemonic = "unimplemented"; const char *form = "'Vdv, 'Pgl, 'Zn.'t"; - - if (instr->Mask(SVEIntReductionLogicalFMask) == SVEIntReductionLogicalFixed) { - switch (instr->Mask(SVEIntReductionLogicalMask)) { - case ANDV_r_p_z: - mnemonic = "andv"; - break; - case EORV_r_p_z: - mnemonic = "eorv"; - break; - case ORV_r_p_z: - mnemonic = "orv"; - break; - default: - break; - } - } else { - switch (instr->Mask(SVEIntReductionMask)) { - case SADDV_r_p_z: - mnemonic = "saddv"; - form = "'Dd, 'Pgl, 'Zn.'t"; - break; - case SMAXV_r_p_z: - mnemonic = "smaxv"; - break; - case SMINV_r_p_z: - mnemonic = "sminv"; - break; - case UADDV_r_p_z: - mnemonic = "uaddv"; - form = "'Dd, 'Pgl, 'Zn.'t"; - break; - case UMAXV_r_p_z: - mnemonic = "umaxv"; - break; - case UMINV_r_p_z: - mnemonic = "uminv"; - break; - default: - break; - } + switch (form_hash_) { + case "saddv_r_p_z"_h: + case "uaddv_r_p_z"_h: + form = "'Dd, 'Pgl, 'Zn.'t"; + break; } - Format(instr, mnemonic, form); + FormatWithDecodedMnemonic(instr, form); } void Disassembler::VisitSVEIntUnaryArithmeticPredicated( @@ -7086,24 +6500,16 @@ void Disassembler::VisitSVEIntUnaryArithmeticPredicated( } void Disassembler::VisitSVEMulIndex(const Instruction *instr) { - const char *mnemonic = mnemonic_.c_str(); - const char *form = "(SVEMulIndex)"; + const char *form = "'Zd.s, 'Zn.b, z'u1816.b['u2019]"; switch (form_hash_) { case "sdot_z_zzzi_d"_h: case "udot_z_zzzi_d"_h: form = "'Zd.d, 'Zn.h, z'u1916.h['u2020]"; break; - case "sdot_z_zzzi_s"_h: - case "sudot_z_zzzi_s"_h: - case "udot_z_zzzi_s"_h: - case "usdot_z_zzzi_s"_h: - form = "'Zd.s, 'Zn.b, z'u1816.b['u2019]"; - break; - default: - break; } - Format(instr, mnemonic, form); + + FormatWithDecodedMnemonic(instr, form); } void Disassembler::VisitSVEPermuteVectorExtract(const Instruction *instr) { @@ -7239,22 +6645,14 @@ void Disassembler::VisitSVEStackFrameSize(const Instruction *instr) { } void Disassembler::VisitSVEVectorSelect(const Instruction *instr) { - const char *mnemonic = "unimplemented"; - const char *form = "(SVEVectorSelect)"; + const char *mnemonic = mnemonic_.c_str(); + const char *form = "'Zd.'t, p'u1310, 'Zn.'t, 'Zm.'t"; - switch (instr->Mask(SVEVectorSelectMask)) { - case SEL_z_p_zz: - if (instr->GetRd() == instr->GetRm()) { - mnemonic = "mov"; - form = "'Zd.'t, p'u1310/m, 'Zn.'t"; - } else { - mnemonic = "sel"; - form = "'Zd.'t, p'u1310, 'Zn.'t, 'Zm.'t"; - } - break; - default: - break; + if (instr->GetRd() == instr->GetRm()) { + mnemonic = "mov"; + form = "'Zd.'t, p'u1310/m, 'Zn.'t"; } + Format(instr, mnemonic, form); } |