diff options
author | Martyn Capewell <martyn.capewell@arm.com> | 2020-06-26 16:43:34 +0100 |
---|---|---|
committer | Martyn Capewell <martyn.capewell@arm.com> | 2020-06-26 16:43:34 +0100 |
commit | 9927c4f6e202de276501cb650ae634907366707e (patch) | |
tree | 940ef0bd80b4e715efc6e6c09ab8c0e053ab686c /src | |
parent | f67b1af0e7b1ca2bc15d649d8a7d145e8ccbf1c9 (diff) | |
download | vixl-9927c4f6e202de276501cb650ae634907366707e.tar.gz |
[sve] Improve disasm substitution for sign-extending loads
Change 'tlss substitution to consider element size and memory size, which
simplifies the code in the visitors.
Change-Id: I0f34f206c6c68d0ddc6b4b115b982268f4dd89be
Diffstat (limited to 'src')
-rw-r--r-- | src/aarch64/disasm-aarch64.cc | 73 |
1 files changed, 33 insertions, 40 deletions
diff --git a/src/aarch64/disasm-aarch64.cc b/src/aarch64/disasm-aarch64.cc index 5b8f6b5c..a2bf53ee 100644 --- a/src/aarch64/disasm-aarch64.cc +++ b/src/aarch64/disasm-aarch64.cc @@ -6120,12 +6120,11 @@ void Disassembler::VisitSVEConstructivePrefix_Unpredicated( void Disassembler::VisitSVEContiguousFirstFaultLoad_ScalarPlusScalar( const Instruction *instr) { const char *mnemonic = "unimplemented"; - const char *form = "(SVEContiguousFirstFaultLoad_ScalarPlusScalar)"; bool rm_is_zr = instr->GetRm() == kZeroRegCode; - const char *form_zr = "{'Zt.'tls}, 'Pgl/z, ['Xns]"; - const char *form_zr_s = "{'Zt.'tlss}, 'Pgl/z, ['Xns]"; + const char *form = "{'Zt.'tlss}, 'Pgl/z, ['Xns"; + const char *suffix = NULL; switch (instr->Mask(SVEContiguousFirstFaultLoad_ScalarPlusScalarMask)) { case LDFF1B_z_p_br_u16: @@ -6133,49 +6132,50 @@ void Disassembler::VisitSVEContiguousFirstFaultLoad_ScalarPlusScalar( case LDFF1B_z_p_br_u64: case LDFF1B_z_p_br_u8: mnemonic = "ldff1b"; - form = rm_is_zr ? form_zr : "{'Zt.'tls}, 'Pgl/z, ['Xns, 'Xm]"; + suffix = rm_is_zr ? "]" : ", 'Xm]"; break; case LDFF1D_z_p_br_u64: mnemonic = "ldff1d"; - form = rm_is_zr ? form_zr : "{'Zt.'tls}, 'Pgl/z, ['Xns, 'Xm, lsl #3]"; + suffix = rm_is_zr ? "]" : ", 'Xm, lsl #3]"; break; case LDFF1H_z_p_br_u16: case LDFF1H_z_p_br_u32: case LDFF1H_z_p_br_u64: mnemonic = "ldff1h"; - form = rm_is_zr ? form_zr : "{'Zt.'tls}, 'Pgl/z, ['Xns, 'Xm, lsl #1]"; + suffix = rm_is_zr ? "]" : ", 'Xm, lsl #1]"; break; case LDFF1SB_z_p_br_s16: case LDFF1SB_z_p_br_s32: case LDFF1SB_z_p_br_s64: mnemonic = "ldff1sb"; - form = rm_is_zr ? form_zr_s : "{'Zt.'tlss}, 'Pgl/z, ['Xns, 'Xm]"; + suffix = rm_is_zr ? "]" : ", 'Xm]"; break; case LDFF1SH_z_p_br_s32: case LDFF1SH_z_p_br_s64: mnemonic = "ldff1sh"; - form = rm_is_zr ? form_zr_s : "{'Zt.'tlss}, 'Pgl/z, ['Xns, 'Xm, lsl #1]"; + suffix = rm_is_zr ? "]" : ", 'Xm, lsl #1]"; break; case LDFF1SW_z_p_br_s64: mnemonic = "ldff1sw"; - form = rm_is_zr ? form_zr_s : "{'Zt.'tlss}, 'Pgl/z, ['Xns, 'Xm, lsl #2]"; + suffix = rm_is_zr ? "]" : ", 'Xm, lsl #2]"; break; case LDFF1W_z_p_br_u32: case LDFF1W_z_p_br_u64: mnemonic = "ldff1w"; - form = rm_is_zr ? form_zr : "{'Zt.'tls}, 'Pgl/z, ['Xns, 'Xm, lsl #2]"; + suffix = rm_is_zr ? "]" : ", 'Xm, lsl #2]"; break; default: + form = "(SVEContiguousFirstFaultLoad_ScalarPlusScalar)"; break; } - Format(instr, mnemonic, form); + Format(instr, mnemonic, form, suffix); } void Disassembler::VisitSVEContiguousNonFaultLoad_ScalarPlusImm( const Instruction *instr) { const char *mnemonic = "unimplemented"; - const char *form = "{'Zt.'tls}, 'Pgl/z, ['Xns"; + const char *form = "{'Zt.'tlss}, 'Pgl/z, ['Xns"; const char *suffix = (instr->ExtractBits(19, 16) == 0) ? "]" : ", #'s1916, mul vl]"; @@ -6197,16 +6197,13 @@ void Disassembler::VisitSVEContiguousNonFaultLoad_ScalarPlusImm( case LDNF1SB_z_p_bi_s16: case LDNF1SB_z_p_bi_s32: case LDNF1SB_z_p_bi_s64: - form = "{'Zt.'tlss}, 'Pgl/z, ['Xns"; mnemonic = "ldnf1sb"; break; case LDNF1SH_z_p_bi_s32: case LDNF1SH_z_p_bi_s64: - form = "{'Zt.'tlss}, 'Pgl/z, ['Xns"; mnemonic = "ldnf1sh"; break; case LDNF1SW_z_p_bi_s64: - form = "{'Zt.'tlss}, 'Pgl/z, ['Xns"; mnemonic = "ldnf1sw"; break; case LDNF1W_z_p_bi_u32: @@ -9400,7 +9397,10 @@ void Disassembler::VisitSVEVectorSelect(const Instruction *instr) { void Disassembler::VisitSVEContiguousLoad_ScalarPlusImm( const Instruction *instr) { const char *mnemonic = "unimplemented"; - bool is_signed = false; + const char *form = "{'Zt.'tlss}, 'Pgl/z, ['Xns"; + const char *suffix = + (instr->ExtractBits(19, 16) == 0) ? "]" : ", #'s1916, mul vl]"; + switch (instr->Mask(SVEContiguousLoad_ScalarPlusImmMask)) { case LD1B_z_p_bi_u16: case LD1B_z_p_bi_u32: @@ -9420,42 +9420,32 @@ void Disassembler::VisitSVEContiguousLoad_ScalarPlusImm( case LD1SB_z_p_bi_s32: case LD1SB_z_p_bi_s64: mnemonic = "ld1sb"; - is_signed = true; break; case LD1SH_z_p_bi_s32: case LD1SH_z_p_bi_s64: mnemonic = "ld1sh"; - is_signed = true; break; case LD1SW_z_p_bi_s64: mnemonic = "ld1sw"; - is_signed = true; break; case LD1W_z_p_bi_u32: case LD1W_z_p_bi_u64: mnemonic = "ld1w"; break; default: + form = "(SVEContiguousLoad_ScalarPlusImm)"; + suffix = NULL; break; } - const char *form; - // The 'size' field isn't in the usual place here. - if (instr->ExtractBits(19, 16) == 0) { - form = is_signed ? "{'Zt.'tlss}, 'Pgl/z, ['Xns]" - : "{'Zt.'tls}, 'Pgl/z, ['Xns]"; - } else { - form = is_signed ? "{'Zt.'tlss}, 'Pgl/z, ['Xns, #'s1916, mul vl]" - : "{'Zt.'tls}, 'Pgl/z, ['Xns, #'s1916, mul vl]"; - } - - Format(instr, mnemonic, form); + Format(instr, mnemonic, form, suffix); } void Disassembler::VisitSVEContiguousLoad_ScalarPlusScalar( const Instruction *instr) { const char *mnemonic = "unimplemented"; - const char *form = "(SVEContiguousLoad_ScalarPlusScalar)"; + const char *form = "{'Zt.'tlss}, 'Pgl/z, ['Xns, 'Xm"; + const char *suffix = NULL; switch (instr->Mask(SVEContiguousLoad_ScalarPlusScalarMask)) { case LD1B_z_p_br_u16: @@ -9463,43 +9453,45 @@ void Disassembler::VisitSVEContiguousLoad_ScalarPlusScalar( case LD1B_z_p_br_u64: case LD1B_z_p_br_u8: mnemonic = "ld1b"; - form = "{'Zt.'tls}, 'Pgl/z, ['Xns, 'Xm]"; + suffix = "]"; break; case LD1D_z_p_br_u64: mnemonic = "ld1d"; - form = "{'Zt.'tls}, 'Pgl/z, ['Xns, 'Xm, lsl #'u2423]"; + suffix = ", lsl #'u2423]"; break; case LD1H_z_p_br_u16: case LD1H_z_p_br_u32: case LD1H_z_p_br_u64: mnemonic = "ld1h"; - form = "{'Zt.'tls}, 'Pgl/z, ['Xns, 'Xm, lsl #'u2423]"; + suffix = ", lsl #'u2423]"; break; case LD1SB_z_p_br_s16: case LD1SB_z_p_br_s32: case LD1SB_z_p_br_s64: mnemonic = "ld1sb"; - form = "{'Zt.'tlss}, 'Pgl/z, ['Xns, 'Xm]"; + suffix = "]"; break; case LD1SH_z_p_br_s32: case LD1SH_z_p_br_s64: mnemonic = "ld1sh"; - form = "{'Zt.'tlss}, 'Pgl/z, ['Xns, 'Xm, lsl #1]"; + suffix = ", lsl #1]"; break; case LD1SW_z_p_br_s64: mnemonic = "ld1sw"; - form = "{'Zt.'tlss}, 'Pgl/z, ['Xns, 'Xm, lsl #2]"; + suffix = ", lsl #2]"; break; case LD1W_z_p_br_u32: case LD1W_z_p_br_u64: mnemonic = "ld1w"; - form = "{'Zt.'tls}, 'Pgl/z, ['Xns, 'Xm, lsl #'u2423]"; + suffix = ", lsl #'u2423]"; break; default: + form = "(SVEContiguousLoad_ScalarPlusScalar)"; + suffix = NULL; break; } - Format(instr, mnemonic, form); + Format(instr, mnemonic, form, suffix); } void Disassembler::VisitReserved(const Instruction *instr) { @@ -10822,7 +10814,8 @@ int Disassembler::SubstituteSVESize(const Instruction *instr, placeholder_length++; if (format[3] == 's') { // Sign extension load. - size_in_bytes_log2 ^= 0x3; + unsigned msize = instr->ExtractBits(24, 23); + if (msize > size_in_bytes_log2) size_in_bytes_log2 ^= 0x3; placeholder_length++; } } else { |