diff options
author | Simon Tatham <simon.tatham@arm.com> | 2019-06-25 11:24:18 +0000 |
---|---|---|
committer | Simon Tatham <simon.tatham@arm.com> | 2019-06-25 11:24:18 +0000 |
commit | e6824160dd6f1edbeac8744a960ef7d3d2ae472a (patch) | |
tree | eae2593e79ec45421e34c0410f9e0e9036db30a0 /llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp | |
parent | 49b3778e32c95175a82ea488f943c1ff9f128851 (diff) | |
download | bcm5719-llvm-e6824160dd6f1edbeac8744a960ef7d3d2ae472a.tar.gz bcm5719-llvm-e6824160dd6f1edbeac8744a960ef7d3d2ae472a.zip |
[ARM] Add MVE vector load/store instructions.
This adds the rest of the vector memory access instructions. It
includes contiguous loads/stores, with an ordinary addressing mode
such as [r0,#offset] (plus writeback variants); gather loads and
scatter stores with a scalar base address register and a vector of
offsets from it (written [r0,q1] or similar); and gather/scatters with
a vector of base addresses (written [q0,#offset], again with
writeback). Additionally, some of the loads can widen each loaded
value into a larger vector lane, and the corresponding stores narrow
them again.
To implement these, we also have to add the addressing modes they
need. Also, in AsmParser, the `isMem` query function now has
subqueries `isGPRMem` and `isMVEMem`, according to which kind of base
register is used by a given memory access operand.
I've also had to add an extra check in `checkTargetMatchPredicate` in
the AsmParser, without which our last-minute check of `rGPR` register
operands against SP and PC was failing an assertion because Tablegen
had inserted an immediate 0 in place of one of a pair of tied register
operands. (This matches the way the corresponding check for `MCK_rGPR`
in `validateTargetOperandClass` is guarded.) Apparently the MVE load
instructions were the first to have ever triggered this assertion, but
I think only because they were the first to have a combination of the
usual Arm pre/post writeback system and the `rGPR` class in particular.
Reviewers: dmgreen, samparker, SjoerdMeijer, t.p.northover
Subscribers: javed.absar, kristof.beyls, hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D62680
llvm-svn: 364291
Diffstat (limited to 'llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 7ccf37ef0e6..dc5dedf9ae3 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -332,6 +332,11 @@ static DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); static DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeMveAddrModeRQ(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); +template<int shift> +static DecodeStatus DecodeMveAddrModeQ(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder); static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); static DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn, @@ -428,8 +433,17 @@ static DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val, uint64_t Address, const void *Decoder); static DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); +template<int shift> +static DecodeStatus DecodeT2Imm7(MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder); static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder); +template<int shift> +static DecodeStatus DecodeTAddrModeImm7(MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder); +template<int shift, int WriteBack> +static DecodeStatus DecodeT2AddrModeImm7(MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder); static DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Val, uint64_t Address, const void *Decoder); static DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn, @@ -509,6 +523,15 @@ template<bool Writeback> static DecodeStatus DecodeVSTRVLDR_SYSREG(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder); +template<int shift> +static DecodeStatus DecodeMVE_MEM_1_pre(MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder); +template<int shift> +static DecodeStatus DecodeMVE_MEM_2_pre(MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder); +template<int shift> +static DecodeStatus DecodeMVE_MEM_3_pre(MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder); template<unsigned MinLog, unsigned MaxLog> static DecodeStatus DecodePowerTwoOperand(MCInst &Inst, unsigned Val, uint64_t Address, @@ -4138,6 +4161,21 @@ static DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val, return MCDisassembler::Success; } +template<int shift> +static DecodeStatus DecodeT2Imm7(MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder) { + int imm = Val & 0x7F; + if (Val == 0) + imm = INT32_MIN; + else if (!(Val & 0x80)) + imm *= -1; + if (imm != INT32_MIN) + imm <<= shift; + Inst.addOperand(MCOperand::createImm(imm)); + + return MCDisassembler::Success; +} + static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder) { DecodeStatus S = MCDisassembler::Success; @@ -4184,6 +4222,42 @@ static DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val, return S; } +template<int shift> +static DecodeStatus DecodeTAddrModeImm7(MCInst &Inst, unsigned Val, + uint64_t Address, + const void *Decoder) { + DecodeStatus S = MCDisassembler::Success; + + unsigned Rn = fieldFromInstruction(Val, 8, 3); + unsigned imm = fieldFromInstruction(Val, 0, 8); + + if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder))) + return MCDisassembler::Fail; + if (!Check(S, DecodeT2Imm7<shift>(Inst, imm, Address, Decoder))) + return MCDisassembler::Fail; + + return S; +} + +template<int shift, int WriteBack> +static DecodeStatus DecodeT2AddrModeImm7(MCInst &Inst, unsigned Val, + uint64_t Address, + const void *Decoder) { + DecodeStatus S = MCDisassembler::Success; + + unsigned Rn = fieldFromInstruction(Val, 8, 4); + unsigned imm = fieldFromInstruction(Val, 0, 8); + if (WriteBack) { + if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder))) + return MCDisassembler::Fail; + } else if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) + return MCDisassembler::Fail; + if (!Check(S, DecodeT2Imm7<shift>(Inst, imm, Address, Decoder))) + return MCDisassembler::Fail; + + return S; +} + static DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder) { DecodeStatus S = MCDisassembler::Success; @@ -4331,6 +4405,43 @@ static DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn, return S; } +static DecodeStatus DecodeMveAddrModeRQ(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + DecodeStatus S = MCDisassembler::Success; + unsigned Rn = fieldFromInstruction(Insn, 3, 4); + unsigned Qm = fieldFromInstruction(Insn, 0, 3); + + if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder))) + return MCDisassembler::Fail; + if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder))) + return MCDisassembler::Fail; + + return S; +} + +template<int shift> +static DecodeStatus DecodeMveAddrModeQ(MCInst &Inst, unsigned Insn, + uint64_t Address, const void *Decoder) { + DecodeStatus S = MCDisassembler::Success; + unsigned Qm = fieldFromInstruction(Insn, 8, 3); + int imm = fieldFromInstruction(Insn, 0, 7); + + if (!Check(S, DecodeMQPRRegisterClass(Inst, Qm, Address, Decoder))) + return MCDisassembler::Fail; + + if(!fieldFromInstruction(Insn, 7, 1)) { + if (imm == 0) + imm = INT32_MIN; // indicate -0 + else + imm *= -1; + } + if (imm != INT32_MIN) + imm <<= shift; + Inst.addOperand(MCOperand::createImm(imm)); + + return S; +} + static DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder) { // Val is passed in as S:J1:J2:imm10H:imm10L:'0' @@ -6175,6 +6286,52 @@ static DecodeStatus DecodeVSTRVLDR_SYSREG(MCInst &Inst, unsigned Val, return S; } +static inline DecodeStatus DecodeMVE_MEM_pre( + MCInst &Inst, unsigned Val, uint64_t Address, const void *Decoder, + unsigned Rn, OperandDecoder RnDecoder, OperandDecoder AddrDecoder) { + DecodeStatus S = MCDisassembler::Success; + + unsigned Qd = fieldFromInstruction(Val, 13, 3); + unsigned addr = fieldFromInstruction(Val, 0, 7) | + (fieldFromInstruction(Val, 23, 1) << 7) | (Rn << 8); + + if (!Check(S, RnDecoder(Inst, Rn, Address, Decoder))) + return MCDisassembler::Fail; + if (!Check(S, DecodeMQPRRegisterClass(Inst, Qd, Address, Decoder))) + return MCDisassembler::Fail; + if (!Check(S, AddrDecoder(Inst, addr, Address, Decoder))) + return MCDisassembler::Fail; + + return S; +} + +template <int shift> +static DecodeStatus DecodeMVE_MEM_1_pre(MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder) { + return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder, + fieldFromInstruction(Val, 16, 3), + DecodetGPRRegisterClass, + DecodeTAddrModeImm7<shift>); +} + +template <int shift> +static DecodeStatus DecodeMVE_MEM_2_pre(MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder) { + return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder, + fieldFromInstruction(Val, 16, 4), + DecoderGPRRegisterClass, + DecodeT2AddrModeImm7<shift,1>); +} + +template <int shift> +static DecodeStatus DecodeMVE_MEM_3_pre(MCInst &Inst, unsigned Val, + uint64_t Address, const void *Decoder) { + return DecodeMVE_MEM_pre(Inst, Val, Address, Decoder, + fieldFromInstruction(Val, 17, 3), + DecodeMQPRRegisterClass, + DecodeMveAddrModeQ<shift>); +} + template<unsigned MinLog, unsigned MaxLog> static DecodeStatus DecodePowerTwoOperand(MCInst &Inst, unsigned Val, uint64_t Address, |