diff options
author | Simon Tatham <simon.tatham@arm.com> | 2019-06-13 13:11:13 +0000 |
---|---|---|
committer | Simon Tatham <simon.tatham@arm.com> | 2019-06-13 13:11:13 +0000 |
commit | 286e1d2c2d625839092ee8bef0bdb94b258f363c (patch) | |
tree | 97ad8a02f588716ed4a7a69ab6070a3d312a5c50 /llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp | |
parent | 6b56ad164cedab90a9b79bfd189a1a27622a24fa (diff) | |
download | bcm5719-llvm-286e1d2c2d625839092ee8bef0bdb94b258f363c.tar.gz bcm5719-llvm-286e1d2c2d625839092ee8bef0bdb94b258f363c.zip |
[ARM] Set up infrastructure for MVE vector instructions.
This commit prepares the way to start adding the main collection of
MVE instructions, which operate on the 128-bit vector registers.
The most obvious thing that's needed, and the simplest, is to add the
MQPR register class, which is like the existing QPR except that it has
fewer registers in it.
The more complicated part: MVE defines a system of vector predication,
in which instructions operating on 128-bit vector registers can be
constrained to operate on only a subset of the lanes, using a system
of prefix instructions similar to the existing Thumb IT, in that you
have one prefix instruction which designates up to 4 following
instructions as subject to predication, and within that sequence, the
predicate can be inverted by means of T/E suffixes ('Then' / 'Else').
To support instructions of this type, we've added two new Tablegen
classes `vpred_n` and `vpred_r` for standard clusters of MC operands
to add to a predicated instruction. Both include a flag indicating how
the instruction is predicated at all (options are T, E and 'not
predicated'), and an input register field for the register controlling
the set of active lanes. They differ from each other in that `vpred_r`
also includes an input operand for the previous value of the output
register, for instructions that leave inactive lanes unchanged.
`vpred_n` lacks that extra operand; it will be used for instructions
that don't preserve inactive lanes in their output register (either
because inactive lanes are zeroed, as the MVE load instructions do, or
because the output register isn't a vector at all).
This commit also adds the family of prefix instructions themselves
(VPT / VPST), and all the machinery needed to work with them in
assembly and disassembly (e.g. generating the 't' and 'e' mnemonic
suffixes on disassembled instructions within a predicated block)
I've added a couple of demo instructions that derive from the new
Tablegen base classes and use those two operand clusters. The bulk of
the vector instructions will come in followup commits small enough to
be manageable. (One exception is that I've added the full version of
`isMnemonicVPTPredicable` in the AsmParser, because it seemed
pointless to carefully split it up.)
Reviewers: dmgreen, samparker, SjoerdMeijer, t.p.northover
Subscribers: javed.absar, kristof.beyls, hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D62669
llvm-svn: 363258
Diffstat (limited to 'llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp | 77 |
1 files changed, 76 insertions, 1 deletions
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index 13dca6dc1de..16a27d0b9c9 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp @@ -434,6 +434,13 @@ public: uint32_t getBFAfterTargetOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const; + + uint32_t getVPTMaskOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; + uint32_t getRestrictedCondCodeOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const; }; } // end anonymous namespace @@ -520,7 +527,15 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO, unsigned Reg = MO.getReg(); unsigned RegNo = CTX.getRegisterInfo()->getEncodingValue(Reg); - // Q registers are encoded as 2x their register number. + // In NEON, Q registers are encoded as 2x their register number, + // because they're using the same indices as the D registers they + // overlap. In MVE, there are no 64-bit vector instructions, so + // the encodings all refer to Q-registers by their literal + // register number. + + if (STI.getFeatureBits()[ARM::HasMVEIntegerOps]) + return RegNo; + switch (Reg) { default: return RegNo; @@ -1789,6 +1804,66 @@ ARMMCCodeEmitter::getBFAfterTargetOpValue(const MCInst &MI, unsigned OpIdx, return Diff == 4; } + +uint32_t ARMMCCodeEmitter::getVPTMaskOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI)const { + const MCOperand MO = MI.getOperand(OpIdx); + assert(MO.isImm() && "Unexpected operand type!"); + + int Value = MO.getImm(); + int Imm = 0; + + // VPT Masks are actually encoded as a series of invert/don't invert bits, + // rather than true/false bits. + unsigned PrevBit = 0; + for (int i = 3; i >= 0; --i) { + unsigned Bit = (Value >> i) & 1; + + // Check if we are at the end of the mask. + if ((Value & ~(~0U << i)) == 0) { + Imm |= (1 << i); + break; + } + + // Convert the bit in the mask based on the previous bit. + if (Bit != PrevBit) + Imm |= (1 << i); + + PrevBit = Bit; + } + + return Imm; +} + +uint32_t ARMMCCodeEmitter::getRestrictedCondCodeOpValue( + const MCInst &MI, unsigned OpIdx, SmallVectorImpl<MCFixup> &Fixups, + const MCSubtargetInfo &STI) const { + + const MCOperand MO = MI.getOperand(OpIdx); + assert(MO.isImm() && "Unexpected operand type!"); + + switch (MO.getImm()) { + default: + assert(0 && "Unexpected Condition!"); + return 0; + case ARMCC::HS: + case ARMCC::EQ: + return 0; + case ARMCC::HI: + case ARMCC::NE: + return 1; + case ARMCC::GE: + return 4; + case ARMCC::LT: + return 5; + case ARMCC::GT: + return 6; + case ARMCC::LE: + return 7; + } +} + #include "ARMGenMCCodeEmitter.inc" MCCodeEmitter *llvm::createARMLEMCCodeEmitter(const MCInstrInfo &MCII, |