mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-13 21:05:16 +00:00
Implement TII::get/setExecutionDomain() for ARM.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140653 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
98e933f9ad
commit
13fd601e0f
@ -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());
|
||||
}
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user