diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-09-27 22:57:21 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-09-27 22:57:21 +0000 |
commit | 13fd601e0f1c6d8558c4c2b027dacd148f19e6af (patch) | |
tree | 2ab2c88fde0c6d357fdd7990bcf3b456c11e129d /lib | |
parent | 98e933f9ad3cc2ede3a0a337144a504265d614cd (diff) | |
download | llvm-13fd601e0f1c6d8558c4c2b027dacd148f19e6af.tar.gz llvm-13fd601e0f1c6d8558c4c2b027dacd148f19e6af.tar.bz2 llvm-13fd601e0f1c6d8558c4c2b027dacd148f19e6af.tar.xz |
Implement TII::get/setExecutionDomain() for ARM.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140653 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM/ARMBaseInstrInfo.cpp | 53 | ||||
-rw-r--r-- | lib/Target/ARM/ARMBaseInstrInfo.h | 6 |
2 files changed, 59 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 1c36cd08f6..70ac487e4b 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -2720,3 +2720,56 @@ ARMBaseInstrInfo::isFpMLxInstruction(unsigned Opcode, unsigned &MulOpc, HasLane = Entry.HasLane; return true; } + +//===----------------------------------------------------------------------===// +// Execution domains. +//===----------------------------------------------------------------------===// +// +// Some instructions go down the NEON pipeline, some go down the VFP pipeline, +// and some can go down both. The vmov instructions go down the VFP pipeline, +// but they can be changed to vorr equivalents that are executed by the NEON +// pipeline. +// +// We use the following execution domain numbering: +// +// 0: Generic +// 1: VFP +// 2: NEON +// +// Also see ARMInstrFormats.td and Domain* enums in ARMBaseInfo.h +// +std::pair<uint16_t, uint16_t> +ARMBaseInstrInfo::getExecutionDomain(const MachineInstr *MI) const { + // VMOVD is a VFP instruction, but can be changed to NEON if it isn't + // predicated. + if (MI->getOpcode() == ARM::VMOVD && !isPredicated(MI)) + return std::make_pair(1, 3); + + // No other instructions can be swizzled, so just determine their domain. + unsigned Domain = MI->getDesc().TSFlags & ARMII::DomainMask; + + if (Domain & ARMII::DomainNEON) + return std::make_pair(2, 0); + + // Certain instructions can go either way on Cortex-A8. + // Treat them as NEON instructions. + if ((Domain & ARMII::DomainNEONA8) && Subtarget.isCortexA8()) + return std::make_pair(2, 0); + + if (Domain & ARMII::DomainVFP) + return std::make_pair(1, 0); + + return std::make_pair(0, 0); +} + +void +ARMBaseInstrInfo::setExecutionDomain(MachineInstr *MI, unsigned Domain) const { + // We only know how to change VMOVD into VORR. + assert(MI->getOpcode() == ARM::VMOVD && "Can only swizzle VMOVD"); + if (Domain != 2) + return; + + // Change to a VORRd which requires two identical use operands. + MI->setDesc(get(ARM::VORRd)); + MachineInstrBuilder(MI).addReg(MI->getOperand(1).getReg()); +} diff --git a/lib/Target/ARM/ARMBaseInstrInfo.h b/lib/Target/ARM/ARMBaseInstrInfo.h index 8ba64d0307..30dd6973fd 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.h +++ b/lib/Target/ARM/ARMBaseInstrInfo.h @@ -210,6 +210,12 @@ public: int getOperandLatency(const InstrItineraryData *ItinData, SDNode *DefNode, unsigned DefIdx, SDNode *UseNode, unsigned UseIdx) const; + + /// VFP/NEON execution domains. + std::pair<uint16_t, uint16_t> + getExecutionDomain(const MachineInstr *MI) const; + void setExecutionDomain(MachineInstr *MI, unsigned Domain) const; + private: int getVLDMDefCycle(const InstrItineraryData *ItinData, const MCInstrDesc &DefMCID, |