summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-09-27 22:57:21 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-09-27 22:57:21 +0000
commit13fd601e0f1c6d8558c4c2b027dacd148f19e6af (patch)
tree2ab2c88fde0c6d357fdd7990bcf3b456c11e129d /lib
parent98e933f9ad3cc2ede3a0a337144a504265d614cd (diff)
downloadllvm-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.cpp53
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.h6
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,