mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-21 18:29:46 +00:00
HexagonPacketizer patch.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154616 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c68dda815e
commit
d1a87a6806
@ -28,6 +28,7 @@
|
||||
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include <map>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -36,7 +37,7 @@ class MachineInstr;
|
||||
class MachineLoopInfo;
|
||||
class MachineDominatorTree;
|
||||
class InstrItineraryData;
|
||||
class ScheduleDAGInstrs;
|
||||
class DefaultVLIWScheduler;
|
||||
class SUnit;
|
||||
|
||||
class DFAPacketizer {
|
||||
@ -77,6 +78,8 @@ public:
|
||||
// reserveResources - Reserve the resources occupied by a machine
|
||||
// instruction and change the current state to reflect that change.
|
||||
void reserveResources(llvm::MachineInstr *MI);
|
||||
|
||||
const InstrItineraryData *getInstrItins() const { return InstrItins; }
|
||||
};
|
||||
|
||||
// VLIWPacketizerList - Implements a simple VLIW packetizer using DFA. The
|
||||
@ -87,20 +90,21 @@ public:
|
||||
// and machine resource is marked as taken. If any dependency is found, a target
|
||||
// API call is made to prune the dependence.
|
||||
class VLIWPacketizerList {
|
||||
protected:
|
||||
const TargetMachine &TM;
|
||||
const MachineFunction &MF;
|
||||
const TargetInstrInfo *TII;
|
||||
|
||||
// Encapsulate data types not exposed to the target interface.
|
||||
ScheduleDAGInstrs *SchedulerImpl;
|
||||
// The VLIW Scheduler.
|
||||
DefaultVLIWScheduler *VLIWScheduler;
|
||||
|
||||
protected:
|
||||
// Vector of instructions assigned to the current packet.
|
||||
std::vector<MachineInstr*> CurrentPacketMIs;
|
||||
// DFA resource tracker.
|
||||
DFAPacketizer *ResourceTracker;
|
||||
// Scheduling units.
|
||||
std::vector<SUnit> SUnits;
|
||||
|
||||
// Generate MI -> SU map.
|
||||
std::map<MachineInstr*, SUnit*> MIToSUnit;
|
||||
|
||||
public:
|
||||
VLIWPacketizerList(
|
||||
@ -118,17 +122,32 @@ public:
|
||||
DFAPacketizer *getResourceTracker() {return ResourceTracker;}
|
||||
|
||||
// addToPacket - Add MI to the current packet.
|
||||
void addToPacket(MachineInstr *MI);
|
||||
virtual MachineBasicBlock::iterator addToPacket(MachineInstr *MI) {
|
||||
MachineBasicBlock::iterator MII = MI;
|
||||
CurrentPacketMIs.push_back(MI);
|
||||
ResourceTracker->reserveResources(MI);
|
||||
return MII;
|
||||
}
|
||||
|
||||
// endPacket - End the current packet.
|
||||
void endPacket(MachineBasicBlock *MBB, MachineInstr *I);
|
||||
void endPacket(MachineBasicBlock *MBB, MachineInstr *MI);
|
||||
|
||||
// initPacketizerState - perform initialization before packetizing
|
||||
// an instruction. This function is supposed to be overrided by
|
||||
// the target dependent packetizer.
|
||||
virtual void initPacketizerState(void) { return; }
|
||||
|
||||
// ignorePseudoInstruction - Ignore bundling of pseudo instructions.
|
||||
bool ignorePseudoInstruction(MachineInstr *I, MachineBasicBlock *MBB);
|
||||
virtual bool ignorePseudoInstruction(MachineInstr *I,
|
||||
MachineBasicBlock *MBB) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// isSoloInstruction - return true if instruction I must end previous
|
||||
// packet.
|
||||
bool isSoloInstruction(MachineInstr *I);
|
||||
// isSoloInstruction - return true if instruction MI can not be packetized
|
||||
// with any other instruction, which means that MI itself is a packet.
|
||||
virtual bool isSoloInstruction(MachineInstr *MI) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// isLegalToPacketizeTogether - Is it legal to packetize SUI and SUJ
|
||||
// together.
|
||||
@ -141,6 +160,7 @@ public:
|
||||
virtual bool isLegalToPruneDependencies(SUnit *SUI, SUnit *SUJ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -23,10 +23,10 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
|
||||
#include "llvm/CodeGen/DFAPacketizer.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineInstrBundle.h"
|
||||
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/MC/MCInstrItineraries.h"
|
||||
using namespace llvm;
|
||||
@ -100,17 +100,17 @@ void DFAPacketizer::reserveResources(llvm::MachineInstr *MI) {
|
||||
reserveResources(&MID);
|
||||
}
|
||||
|
||||
namespace {
|
||||
namespace llvm {
|
||||
// DefaultVLIWScheduler - This class extends ScheduleDAGInstrs and overrides
|
||||
// Schedule method to build the dependence graph.
|
||||
class DefaultVLIWScheduler : public ScheduleDAGInstrs {
|
||||
public:
|
||||
DefaultVLIWScheduler(MachineFunction &MF, MachineLoopInfo &MLI,
|
||||
MachineDominatorTree &MDT, bool IsPostRA);
|
||||
MachineDominatorTree &MDT, bool IsPostRA);
|
||||
// Schedule - Actual scheduling work.
|
||||
void schedule();
|
||||
};
|
||||
} // end anonymous namespace
|
||||
}
|
||||
|
||||
DefaultVLIWScheduler::DefaultVLIWScheduler(
|
||||
MachineFunction &MF, MachineLoopInfo &MLI, MachineDominatorTree &MDT,
|
||||
@ -129,49 +129,25 @@ VLIWPacketizerList::VLIWPacketizerList(
|
||||
bool IsPostRA) : TM(MF.getTarget()), MF(MF) {
|
||||
TII = TM.getInstrInfo();
|
||||
ResourceTracker = TII->CreateTargetScheduleState(&TM, 0);
|
||||
SchedulerImpl = new DefaultVLIWScheduler(MF, MLI, MDT, IsPostRA);
|
||||
VLIWScheduler = new DefaultVLIWScheduler(MF, MLI, MDT, IsPostRA);
|
||||
}
|
||||
|
||||
// VLIWPacketizerList Dtor
|
||||
VLIWPacketizerList::~VLIWPacketizerList() {
|
||||
delete SchedulerImpl;
|
||||
delete ResourceTracker;
|
||||
}
|
||||
if (VLIWScheduler)
|
||||
delete VLIWScheduler;
|
||||
|
||||
// ignorePseudoInstruction - ignore pseudo instructions.
|
||||
bool VLIWPacketizerList::ignorePseudoInstruction(MachineInstr *MI,
|
||||
MachineBasicBlock *MBB) {
|
||||
if (MI->isDebugValue())
|
||||
return true;
|
||||
|
||||
if (TII->isSchedulingBoundary(MI, MBB, MF))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// isSoloInstruction - return true if instruction I must end previous
|
||||
// packet.
|
||||
bool VLIWPacketizerList::isSoloInstruction(MachineInstr *I) {
|
||||
if (I->isInlineAsm())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// addToPacket - Add I to the current packet and reserve resource.
|
||||
void VLIWPacketizerList::addToPacket(MachineInstr *MI) {
|
||||
CurrentPacketMIs.push_back(MI);
|
||||
ResourceTracker->reserveResources(MI);
|
||||
if (ResourceTracker)
|
||||
delete ResourceTracker;
|
||||
}
|
||||
|
||||
// endPacket - End the current packet, bundle packet instructions and reset
|
||||
// DFA state.
|
||||
void VLIWPacketizerList::endPacket(MachineBasicBlock *MBB,
|
||||
MachineInstr *I) {
|
||||
MachineInstr *MI) {
|
||||
if (CurrentPacketMIs.size() > 1) {
|
||||
MachineInstr *MIFirst = CurrentPacketMIs.front();
|
||||
finalizeBundle(*MBB, MIFirst, I);
|
||||
finalizeBundle(*MBB, MIFirst, MI);
|
||||
}
|
||||
CurrentPacketMIs.clear();
|
||||
ResourceTracker->clearResources();
|
||||
@ -181,31 +157,36 @@ void VLIWPacketizerList::endPacket(MachineBasicBlock *MBB,
|
||||
void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB,
|
||||
MachineBasicBlock::iterator BeginItr,
|
||||
MachineBasicBlock::iterator EndItr) {
|
||||
assert(MBB->end() == EndItr && "Bad EndIndex");
|
||||
assert(VLIWScheduler && "VLIW Scheduler is not initialized!");
|
||||
VLIWScheduler->enterRegion(MBB, BeginItr, EndItr, MBB->size());
|
||||
VLIWScheduler->schedule();
|
||||
VLIWScheduler->exitRegion();
|
||||
|
||||
SchedulerImpl->enterRegion(MBB, BeginItr, EndItr, MBB->size());
|
||||
|
||||
// Build the DAG without reordering instructions.
|
||||
SchedulerImpl->schedule();
|
||||
|
||||
// Remember scheduling units.
|
||||
SUnits = SchedulerImpl->SUnits;
|
||||
// Generate MI -> SU map.
|
||||
//std::map <MachineInstr*, SUnit*> MIToSUnit;
|
||||
MIToSUnit.clear();
|
||||
for (unsigned i = 0, e = VLIWScheduler->SUnits.size(); i != e; ++i) {
|
||||
SUnit *SU = &VLIWScheduler->SUnits[i];
|
||||
MIToSUnit[SU->getInstr()] = SU;
|
||||
}
|
||||
|
||||
// The main packetizer loop.
|
||||
for (; BeginItr != EndItr; ++BeginItr) {
|
||||
MachineInstr *MI = BeginItr;
|
||||
|
||||
// Ignore pseudo instructions.
|
||||
if (ignorePseudoInstruction(MI, MBB))
|
||||
continue;
|
||||
this->initPacketizerState();
|
||||
|
||||
// End the current packet if needed.
|
||||
if (isSoloInstruction(MI)) {
|
||||
if (this->isSoloInstruction(MI)) {
|
||||
endPacket(MBB, MI);
|
||||
continue;
|
||||
}
|
||||
|
||||
SUnit *SUI = SchedulerImpl->getSUnit(MI);
|
||||
// Ignore pseudo instructions.
|
||||
if (this->ignorePseudoInstruction(MI, MBB))
|
||||
continue;
|
||||
|
||||
SUnit *SUI = MIToSUnit[MI];
|
||||
assert(SUI && "Missing SUnit Info!");
|
||||
|
||||
// Ask DFA if machine resource is available for MI.
|
||||
@ -215,13 +196,13 @@ void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB,
|
||||
for (std::vector<MachineInstr*>::iterator VI = CurrentPacketMIs.begin(),
|
||||
VE = CurrentPacketMIs.end(); VI != VE; ++VI) {
|
||||
MachineInstr *MJ = *VI;
|
||||
SUnit *SUJ = SchedulerImpl->getSUnit(MJ);
|
||||
SUnit *SUJ = MIToSUnit[MJ];
|
||||
assert(SUJ && "Missing SUnit Info!");
|
||||
|
||||
// Is it legal to packetize SUI and SUJ together.
|
||||
if (!isLegalToPacketizeTogether(SUI, SUJ)) {
|
||||
if (!this->isLegalToPacketizeTogether(SUI, SUJ)) {
|
||||
// Allow packetization if dependency can be pruned.
|
||||
if (!isLegalToPruneDependencies(SUI, SUJ)) {
|
||||
if (!this->isLegalToPruneDependencies(SUI, SUJ)) {
|
||||
// End the packet if dependency cannot be pruned.
|
||||
endPacket(MBB, MI);
|
||||
break;
|
||||
@ -234,11 +215,9 @@ void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB,
|
||||
}
|
||||
|
||||
// Add MI to the current packet.
|
||||
addToPacket(MI);
|
||||
BeginItr = this->addToPacket(MI);
|
||||
} // For all instructions in BB.
|
||||
|
||||
// End any packet left behind.
|
||||
endPacket(MBB, EndItr);
|
||||
|
||||
SchedulerImpl->exitRegion();
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ add_llvm_target(HexagonCodeGen
|
||||
HexagonSplitTFRCondSets.cpp
|
||||
HexagonSubtarget.cpp
|
||||
HexagonTargetMachine.cpp
|
||||
HexagonTargetObjectFile.cpp
|
||||
HexagonVLIWPacketizer.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(TargetInfo)
|
||||
|
@ -40,6 +40,7 @@ namespace llvm {
|
||||
FunctionPass *createHexagonHardwareLoops();
|
||||
FunctionPass *createHexagonPeephole();
|
||||
FunctionPass *createHexagonFixupHwLoops();
|
||||
FunctionPass *createHexagonPacketizer();
|
||||
|
||||
/* TODO: object output.
|
||||
MCCodeEmitter *createHexagonMCCodeEmitter(const Target &,
|
||||
|
@ -13,11 +13,11 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#define DEBUG_TYPE "asm-printer"
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonAsmPrinter.h"
|
||||
#include "HexagonMachineFunctionInfo.h"
|
||||
#include "HexagonMCInst.h"
|
||||
#include "HexagonTargetMachine.h"
|
||||
#include "HexagonSubtarget.h"
|
||||
#include "InstPrinter/HexagonInstPrinter.h"
|
||||
@ -54,6 +54,7 @@
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include <map>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@ -196,10 +197,45 @@ void HexagonAsmPrinter::printPredicateOperand(const MachineInstr *MI,
|
||||
/// the current output stream.
|
||||
///
|
||||
void HexagonAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
MCInst MCI;
|
||||
if (MI->isBundle()) {
|
||||
std::vector<const MachineInstr*> BundleMIs;
|
||||
|
||||
HexagonLowerToMC(MI, MCI, *this);
|
||||
OutStreamer.EmitInstruction(MCI);
|
||||
const MachineBasicBlock *MBB = MI->getParent();
|
||||
MachineBasicBlock::const_instr_iterator MII = MI;
|
||||
++MII;
|
||||
unsigned int IgnoreCount = 0;
|
||||
while (MII != MBB->end() && MII->isInsideBundle()) {
|
||||
const MachineInstr *MInst = MII;
|
||||
if (MInst->getOpcode() == TargetOpcode::DBG_VALUE ||
|
||||
MInst->getOpcode() == TargetOpcode::IMPLICIT_DEF) {
|
||||
IgnoreCount++;
|
||||
++MII;
|
||||
continue;
|
||||
}
|
||||
//BundleMIs.push_back(&*MII);
|
||||
BundleMIs.push_back(MInst);
|
||||
++MII;
|
||||
}
|
||||
unsigned Size = BundleMIs.size();
|
||||
assert((Size+IgnoreCount) == MI->getBundleSize() && "Corrupt Bundle!");
|
||||
for (unsigned Index = 0; Index < Size; Index++) {
|
||||
HexagonMCInst MCI;
|
||||
MCI.setStartPacket(Index == 0);
|
||||
MCI.setEndPacket(Index == (Size-1));
|
||||
|
||||
HexagonLowerToMC(BundleMIs[Index], MCI, *this);
|
||||
OutStreamer.EmitInstruction(MCI);
|
||||
}
|
||||
}
|
||||
else {
|
||||
HexagonMCInst MCI;
|
||||
if (MI->getOpcode() == Hexagon::ENDLOOP0) {
|
||||
MCI.setStartPacket(true);
|
||||
MCI.setEndPacket(true);
|
||||
}
|
||||
HexagonLowerToMC(MI, MCI, *this);
|
||||
OutStreamer.EmitInstruction(MCI);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@ -242,17 +278,17 @@ void HexagonAsmPrinter::printJumpTable(const MachineInstr *MI, int OpNo,
|
||||
raw_ostream &O) {
|
||||
const MachineOperand &MO = MI->getOperand(OpNo);
|
||||
assert( (MO.getType() == MachineOperand::MO_JumpTableIndex) &&
|
||||
"Expecting jump table index");
|
||||
"Expecting jump table index");
|
||||
|
||||
// Hexagon_TODO: Do we need name mangling?
|
||||
O << *GetJTISymbol(MO.getIndex());
|
||||
}
|
||||
|
||||
void HexagonAsmPrinter::printConstantPool(const MachineInstr *MI, int OpNo,
|
||||
raw_ostream &O) {
|
||||
raw_ostream &O) {
|
||||
const MachineOperand &MO = MI->getOperand(OpNo);
|
||||
assert( (MO.getType() == MachineOperand::MO_ConstantPoolIndex) &&
|
||||
"Expecting constant pool index");
|
||||
"Expecting constant pool index");
|
||||
|
||||
// Hexagon_TODO: Do we need name mangling?
|
||||
O << *GetCPISymbol(MO.getIndex());
|
||||
|
@ -13,13 +13,26 @@
|
||||
// *** Must match HexagonBaseInfo.h ***
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class Type<bits<5> t> {
|
||||
bits<5> Value = t;
|
||||
}
|
||||
def TypePSEUDO : Type<0>;
|
||||
def TypeALU32 : Type<1>;
|
||||
def TypeCR : Type<2>;
|
||||
def TypeJR : Type<3>;
|
||||
def TypeJ : Type<4>;
|
||||
def TypeLD : Type<5>;
|
||||
def TypeST : Type<6>;
|
||||
def TypeSYSTEM : Type<7>;
|
||||
def TypeXTYPE : Type<8>;
|
||||
def TypeMARKER : Type<31>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Intruction Class Declaration +
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
string cstr, InstrItinClass itin> : Instruction {
|
||||
string cstr, InstrItinClass itin, Type type> : Instruction {
|
||||
field bits<32> Inst;
|
||||
|
||||
let Namespace = "Hexagon";
|
||||
@ -31,11 +44,15 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
let Constraints = cstr;
|
||||
let Itinerary = itin;
|
||||
|
||||
// *** The code below must match HexagonBaseInfo.h ***
|
||||
// *** Must match HexagonBaseInfo.h ***
|
||||
Type HexagonType = type;
|
||||
let TSFlags{4-0} = HexagonType.Value;
|
||||
bits<1> isHexagonSolo = 0;
|
||||
let TSFlags{5} = isHexagonSolo;
|
||||
|
||||
// Predicated instructions.
|
||||
bits<1> isPredicated = 0;
|
||||
let TSFlags{1} = isPredicated;
|
||||
let TSFlags{6} = isPredicated;
|
||||
|
||||
// *** The code above must match HexagonBaseInfo.h ***
|
||||
}
|
||||
@ -47,28 +64,40 @@ class InstHexagon<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
// LD Instruction Class in V2/V3/V4.
|
||||
// Definition of the instruction class NOT CHANGED.
|
||||
class LDInst<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", LD> {
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", LD, TypeLD> {
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<13> imm13;
|
||||
let mayLoad = 1;
|
||||
}
|
||||
|
||||
// LD Instruction Class in V2/V3/V4.
|
||||
// Definition of the instruction class NOT CHANGED.
|
||||
class LDInstPost<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
string cstr>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, cstr, LD> {
|
||||
: InstHexagon<outs, ins, asmstr, pattern, cstr, LD, TypeLD> {
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
bits<13> imm13;
|
||||
let mayLoad = 1;
|
||||
}
|
||||
|
||||
// ST Instruction Class in V2/V3 can take SLOT0 only.
|
||||
// ST Instruction Class in V4 can take SLOT0 & SLOT1.
|
||||
// Definition of the instruction class CHANGED from V2/V3 to V4.
|
||||
class STInst<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", ST> {
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", ST, TypeST> {
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<13> imm13;
|
||||
let mayStore = 1;
|
||||
}
|
||||
|
||||
// SYSTEM Instruction Class in V4 can take SLOT0 only
|
||||
// In V2/V3 we used ST for this but in v4 ST can take SLOT0 or SLOT1.
|
||||
class SYSInst<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", SYS, TypeSYSTEM> {
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<13> imm13;
|
||||
@ -79,17 +108,18 @@ class STInst<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
// Definition of the instruction class CHANGED from V2/V3 to V4.
|
||||
class STInstPost<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
string cstr>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, cstr, ST> {
|
||||
: InstHexagon<outs, ins, asmstr, pattern, cstr, ST, TypeST> {
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
bits<13> imm13;
|
||||
let mayStore = 1;
|
||||
}
|
||||
|
||||
// ALU32 Instruction Class in V2/V3/V4.
|
||||
// Definition of the instruction class NOT CHANGED.
|
||||
class ALU32Type<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", ALU32> {
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", ALU32, TypeALU32> {
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
@ -102,7 +132,17 @@ class ALU32Type<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
// Definition of the instruction class NOT CHANGED.
|
||||
// Name of the Instruction Class changed from ALU64 to XTYPE from V2/V3 to V4.
|
||||
class ALU64Type<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", ALU64> {
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", ALU64, TypeXTYPE> {
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
bits<16> imm16;
|
||||
bits<16> imm16_2;
|
||||
}
|
||||
|
||||
class ALU64_acc<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
string cstr>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, cstr, ALU64, TypeXTYPE> {
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
@ -115,7 +155,7 @@ class ALU64Type<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
// Definition of the instruction class NOT CHANGED.
|
||||
// Name of the Instruction Class changed from M to XTYPE from V2/V3 to V4.
|
||||
class MInst<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", M> {
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", M, TypeXTYPE> {
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
@ -126,8 +166,8 @@ class MInst<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
// Definition of the instruction class NOT CHANGED.
|
||||
// Name of the Instruction Class changed from M to XTYPE from V2/V3 to V4.
|
||||
class MInst_acc<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
string cstr>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, cstr, M> {
|
||||
string cstr>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, cstr, M, TypeXTYPE> {
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
@ -138,9 +178,7 @@ class MInst_acc<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
// Definition of the instruction class NOT CHANGED.
|
||||
// Name of the Instruction Class changed from S to XTYPE from V2/V3 to V4.
|
||||
class SInst<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
//: InstHexagon<outs, ins, asmstr, pattern, cstr, !if(V4T, XTYPE_V4, M)> {
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", S> {
|
||||
// : InstHexagon<outs, ins, asmstr, pattern, "", S> {
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", S, TypeXTYPE> {
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
@ -151,8 +189,8 @@ class SInst<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
// Definition of the instruction class NOT CHANGED.
|
||||
// Name of the Instruction Class changed from S to XTYPE from V2/V3 to V4.
|
||||
class SInst_acc<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
string cstr>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, cstr, S> {
|
||||
string cstr>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, cstr, S, TypeXTYPE> {
|
||||
// : InstHexagon<outs, ins, asmstr, pattern, cstr, S> {
|
||||
// : InstHexagon<outs, ins, asmstr, pattern, cstr, !if(V4T, XTYPE_V4, S)> {
|
||||
bits<5> rd;
|
||||
@ -163,14 +201,14 @@ class SInst_acc<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
// J Instruction Class in V2/V3/V4.
|
||||
// Definition of the instruction class NOT CHANGED.
|
||||
class JType<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", J> {
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", J, TypeJ> {
|
||||
bits<16> imm16;
|
||||
}
|
||||
|
||||
// JR Instruction Class in V2/V3/V4.
|
||||
// Definition of the instruction class NOT CHANGED.
|
||||
class JRType<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", JR> {
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", JR, TypeJR> {
|
||||
bits<5> rs;
|
||||
bits<5> pu; // Predicate register
|
||||
}
|
||||
@ -178,15 +216,22 @@ class JRType<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
// CR Instruction Class in V2/V3/V4.
|
||||
// Definition of the instruction class NOT CHANGED.
|
||||
class CRInst<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", CR> {
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", CR, TypeCR> {
|
||||
bits<5> rs;
|
||||
bits<10> imm10;
|
||||
}
|
||||
|
||||
class Marker<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", MARKER, TypeMARKER> {
|
||||
let isCodeGenOnly = 1;
|
||||
let isPseudo = 1;
|
||||
}
|
||||
|
||||
class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", PSEUDO>;
|
||||
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", PSEUDO, TypePSEUDO> {
|
||||
let isCodeGenOnly = 1;
|
||||
let isPseudo = 1;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Intruction Classes Definitions -
|
||||
@ -222,6 +267,11 @@ class ALU64_rr<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: ALU64Type<outs, ins, asmstr, pattern> {
|
||||
}
|
||||
|
||||
class ALU64_ri<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: ALU64Type<outs, ins, asmstr, pattern> {
|
||||
let rt{0-4} = 0;
|
||||
}
|
||||
|
||||
// J Type Instructions.
|
||||
class JInst<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: JType<outs, ins, asmstr, pattern> {
|
||||
@ -237,12 +287,14 @@ class JRInst<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
class STInstPI<dag outs, dag ins, string asmstr, list<dag> pattern, string cstr>
|
||||
: STInstPost<outs, ins, asmstr, pattern, cstr> {
|
||||
let rt{0-4} = 0;
|
||||
let mayStore = 1;
|
||||
}
|
||||
|
||||
// Post increment LD Instruction.
|
||||
class LDInstPI<dag outs, dag ins, string asmstr, list<dag> pattern, string cstr>
|
||||
: LDInstPost<outs, ins, asmstr, pattern, cstr> {
|
||||
let rt{0-4} = 0;
|
||||
let mayLoad = 1;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -11,11 +11,25 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Hexagon Intruction Flags +
|
||||
//
|
||||
// *** Must match BaseInfo.h ***
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
def TypeMEMOP : Type<9>;
|
||||
def TypeNV : Type<10>;
|
||||
def TypePREFIX : Type<30>;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
// Intruction Classes Definitions +
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
//
|
||||
// NV type instructions.
|
||||
//
|
||||
class NVInst_V4<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", NV_V4> {
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", NV_V4, TypeNV> {
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<13> imm13;
|
||||
@ -24,7 +38,7 @@ class NVInst_V4<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
// Definition of Post increment new value store.
|
||||
class NVInstPost_V4<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
string cstr>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, cstr, NV_V4> {
|
||||
: InstHexagon<outs, ins, asmstr, pattern, cstr, NV_V4, TypeNV> {
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<5> rt;
|
||||
@ -39,8 +53,15 @@ class NVInstPI_V4<dag outs, dag ins, string asmstr, list<dag> pattern,
|
||||
}
|
||||
|
||||
class MEMInst_V4<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", MEM_V4> {
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", MEM_V4, TypeMEMOP> {
|
||||
bits<5> rd;
|
||||
bits<5> rs;
|
||||
bits<6> imm6;
|
||||
}
|
||||
|
||||
class Immext<dag outs, dag ins, string asmstr, list<dag> pattern>
|
||||
: InstHexagon<outs, ins, asmstr, pattern, "", PREFIX, TypePREFIX> {
|
||||
let isCodeGenOnly = 1;
|
||||
|
||||
bits<26> imm26;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -160,10 +160,20 @@ public:
|
||||
bool isS8_Immediate(const int value) const;
|
||||
bool isS6_Immediate(const int value) const;
|
||||
|
||||
bool isSaveCalleeSavedRegsCall(const MachineInstr* MI) const;
|
||||
bool isConditionalTransfer(const MachineInstr* MI) const;
|
||||
bool isConditionalALU32 (const MachineInstr* MI) const;
|
||||
bool isConditionalLoad (const MachineInstr* MI) const;
|
||||
bool isConditionalStore(const MachineInstr* MI) const;
|
||||
bool isDeallocRet(const MachineInstr *MI) const;
|
||||
unsigned getInvertedPredicatedOpcode(const int Opc) const;
|
||||
bool isExtendable(const MachineInstr* MI) const;
|
||||
bool isExtended(const MachineInstr* MI) const;
|
||||
bool isPostIncrement(const MachineInstr* MI) const;
|
||||
bool isNewValueStore(const MachineInstr* MI) const;
|
||||
bool isNewValueJump(const MachineInstr* MI) const;
|
||||
unsigned getImmExtForm(const MachineInstr* MI) const;
|
||||
unsigned getNormalBranchForm(const MachineInstr* MI) const;
|
||||
|
||||
private:
|
||||
int getMatchingCondBranchOpcode(int Opc, bool sense) const;
|
||||
|
@ -3046,3 +3046,7 @@ include "HexagonInstrInfoV3.td"
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
include "HexagonInstrInfoV4.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// V4 Instructions -
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -41,10 +41,11 @@ let isCall = 1, neverHasSideEffects = 1,
|
||||
}
|
||||
|
||||
|
||||
// Jump to address from register
|
||||
// if(p?.new) jumpr:t r?
|
||||
let isReturn = 1, isTerminator = 1, isBarrier = 1,
|
||||
Defs = [PC], Uses = [R31] in {
|
||||
def JMPR_cPnewt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
|
||||
def JMPR_cdnPt_V3: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
|
||||
"if ($src1.new) jumpr:t $src2",
|
||||
[]>, Requires<[HasV3T]>;
|
||||
}
|
||||
@ -52,7 +53,7 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1,
|
||||
// if (!p?.new) jumpr:t r?
|
||||
let isReturn = 1, isTerminator = 1, isBarrier = 1,
|
||||
Defs = [PC], Uses = [R31] in {
|
||||
def JMPR_cNotPnewt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
|
||||
def JMPR_cdnNotPt_V3: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
|
||||
"if (!$src1.new) jumpr:t $src2",
|
||||
[]>, Requires<[HasV3T]>;
|
||||
}
|
||||
@ -61,7 +62,7 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1,
|
||||
// if(p?.new) jumpr:nt r?
|
||||
let isReturn = 1, isTerminator = 1, isBarrier = 1,
|
||||
Defs = [PC], Uses = [R31] in {
|
||||
def JMPR_cPnewNt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
|
||||
def JMPR_cdnPnt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
|
||||
"if ($src1.new) jumpr:nt $src2",
|
||||
[]>, Requires<[HasV3T]>;
|
||||
}
|
||||
@ -69,7 +70,7 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1,
|
||||
// if (!p?.new) jumpr:nt r?
|
||||
let isReturn = 1, isTerminator = 1, isBarrier = 1,
|
||||
Defs = [PC], Uses = [R31] in {
|
||||
def JMPR_cNotPnewNt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
|
||||
def JMPR_cdnNotPnt: JRInst<(outs), (ins PredRegs:$src1, IntRegs:$src2),
|
||||
"if (!$src1.new) jumpr:nt $src2",
|
||||
[]>, Requires<[HasV3T]>;
|
||||
}
|
||||
@ -86,20 +87,22 @@ let AddedComplexity = 200 in
|
||||
def MAXw_dd : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
|
||||
DoubleRegs:$src2),
|
||||
"$dst = max($src2, $src1)",
|
||||
[(set DoubleRegs:$dst, (select (i1 (setlt DoubleRegs:$src2,
|
||||
DoubleRegs:$src1)),
|
||||
DoubleRegs:$src1,
|
||||
DoubleRegs:$src2))]>,
|
||||
[(set (i64 DoubleRegs:$dst),
|
||||
(i64 (select (i1 (setlt (i64 DoubleRegs:$src2),
|
||||
(i64 DoubleRegs:$src1))),
|
||||
(i64 DoubleRegs:$src1),
|
||||
(i64 DoubleRegs:$src2))))]>,
|
||||
Requires<[HasV3T]>;
|
||||
|
||||
let AddedComplexity = 200 in
|
||||
def MINw_dd : ALU64_rr<(outs DoubleRegs:$dst), (ins DoubleRegs:$src1,
|
||||
DoubleRegs:$src2),
|
||||
"$dst = min($src2, $src1)",
|
||||
[(set DoubleRegs:$dst, (select (i1 (setgt DoubleRegs:$src2,
|
||||
DoubleRegs:$src1)),
|
||||
DoubleRegs:$src1,
|
||||
DoubleRegs:$src2))]>,
|
||||
[(set (i64 DoubleRegs:$dst),
|
||||
(i64 (select (i1 (setgt (i64 DoubleRegs:$src2),
|
||||
(i64 DoubleRegs:$src1))),
|
||||
(i64 DoubleRegs:$src1),
|
||||
(i64 DoubleRegs:$src2))))]>,
|
||||
Requires<[HasV3T]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -109,25 +112,25 @@ Requires<[HasV3T]>;
|
||||
|
||||
|
||||
|
||||
//def : Pat <(brcond (i1 (seteq IntRegs:$src1, 0)), bb:$offset),
|
||||
// (JMP_RegEzt IntRegs:$src1, bb:$offset)>, Requires<[HasV3T]>;
|
||||
//def : Pat <(brcond (i1 (seteq (i32 IntRegs:$src1), 0)), bb:$offset),
|
||||
// (JMP_RegEzt (i32 IntRegs:$src1), bb:$offset)>, Requires<[HasV3T]>;
|
||||
|
||||
//def : Pat <(brcond (i1 (setne IntRegs:$src1, 0)), bb:$offset),
|
||||
// (JMP_RegNzt IntRegs:$src1, bb:$offset)>, Requires<[HasV3T]>;
|
||||
//def : Pat <(brcond (i1 (setne (i32 IntRegs:$src1), 0)), bb:$offset),
|
||||
// (JMP_RegNzt (i32 IntRegs:$src1), bb:$offset)>, Requires<[HasV3T]>;
|
||||
|
||||
//def : Pat <(brcond (i1 (setle IntRegs:$src1, 0)), bb:$offset),
|
||||
// (JMP_RegLezt IntRegs:$src1, bb:$offset)>, Requires<[HasV3T]>;
|
||||
//def : Pat <(brcond (i1 (setle (i32 IntRegs:$src1), 0)), bb:$offset),
|
||||
// (JMP_RegLezt (i32 IntRegs:$src1), bb:$offset)>, Requires<[HasV3T]>;
|
||||
|
||||
//def : Pat <(brcond (i1 (setge IntRegs:$src1, 0)), bb:$offset),
|
||||
// (JMP_RegGezt IntRegs:$src1, bb:$offset)>, Requires<[HasV3T]>;
|
||||
//def : Pat <(brcond (i1 (setge (i32 IntRegs:$src1), 0)), bb:$offset),
|
||||
// (JMP_RegGezt (i32 IntRegs:$src1), bb:$offset)>, Requires<[HasV3T]>;
|
||||
|
||||
//def : Pat <(brcond (i1 (setgt IntRegs:$src1, -1)), bb:$offset),
|
||||
// (JMP_RegGezt IntRegs:$src1, bb:$offset)>, Requires<[HasV3T]>;
|
||||
//def : Pat <(brcond (i1 (setgt (i32 IntRegs:$src1), -1)), bb:$offset),
|
||||
// (JMP_RegGezt (i32 IntRegs:$src1), bb:$offset)>, Requires<[HasV3T]>;
|
||||
|
||||
|
||||
// Map call instruction
|
||||
def : Pat<(call IntRegs:$dst),
|
||||
(CALLRv3 IntRegs:$dst)>, Requires<[HasV3T]>;
|
||||
def : Pat<(call (i32 IntRegs:$dst)),
|
||||
(CALLRv3 (i32 IntRegs:$dst))>, Requires<[HasV3T]>;
|
||||
def : Pat<(call tglobaladdr:$dst),
|
||||
(CALLv3 tglobaladdr:$dst)>, Requires<[HasV3T]>;
|
||||
def : Pat<(call texternalsym:$dst),
|
||||
|
File diff suppressed because it is too large
Load Diff
41
lib/Target/Hexagon/HexagonMCInst.h
Normal file
41
lib/Target/Hexagon/HexagonMCInst.h
Normal file
@ -0,0 +1,41 @@
|
||||
//===- HexagonMCInst.h - Hexagon sub-class of MCInst ----------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This class extends MCInst to allow some VLIW annotation.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef HEXAGONMCINST_H
|
||||
#define HEXAGONMCINST_H
|
||||
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
|
||||
namespace llvm {
|
||||
class HexagonMCInst: public MCInst {
|
||||
// Packet start and end markers
|
||||
unsigned startPacket: 1, endPacket: 1;
|
||||
const MachineInstr *MachineI;
|
||||
public:
|
||||
explicit HexagonMCInst(): MCInst(),
|
||||
startPacket(0), endPacket(0) {}
|
||||
|
||||
const MachineInstr* getMI() const { return MachineI; };
|
||||
|
||||
void setMI(const MachineInstr *MI) { MachineI = MI; };
|
||||
|
||||
bool isStartPacket() const { return (startPacket); };
|
||||
bool isEndPacket() const { return (endPacket); };
|
||||
|
||||
void setStartPacket(bool yes) { startPacket = yes; };
|
||||
void setEndPacket(bool yes) { endPacket = yes; };
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -13,7 +13,6 @@ def LSUNIT : FuncUnit;
|
||||
def MUNIT : FuncUnit;
|
||||
def SUNIT : FuncUnit;
|
||||
|
||||
|
||||
// Itinerary classes
|
||||
def ALU32 : InstrItinClass;
|
||||
def ALU64 : InstrItinClass;
|
||||
@ -24,23 +23,25 @@ def LD : InstrItinClass;
|
||||
def M : InstrItinClass;
|
||||
def ST : InstrItinClass;
|
||||
def S : InstrItinClass;
|
||||
def SYS : InstrItinClass;
|
||||
def MARKER : InstrItinClass;
|
||||
def PSEUDO : InstrItinClass;
|
||||
|
||||
|
||||
def HexagonItineraries :
|
||||
ProcessorItineraries<[LUNIT, LSUNIT, MUNIT, SUNIT], [], [
|
||||
InstrItinData<ALU32 , [InstrStage<1, [LUNIT, LSUNIT, MUNIT, SUNIT]>]>,
|
||||
InstrItinData<ALU64 , [InstrStage<1, [MUNIT, SUNIT]>]>,
|
||||
InstrItinData<CR , [InstrStage<1, [SUNIT]>]>,
|
||||
InstrItinData<J , [InstrStage<1, [SUNIT, MUNIT]>]>,
|
||||
InstrItinData<JR , [InstrStage<1, [MUNIT]>]>,
|
||||
InstrItinData<LD , [InstrStage<1, [LUNIT, LSUNIT]>]>,
|
||||
InstrItinData<M , [InstrStage<1, [MUNIT, SUNIT]>]>,
|
||||
InstrItinData<ST , [InstrStage<1, [LSUNIT]>]>,
|
||||
InstrItinData<S , [InstrStage<1, [SUNIT, MUNIT]>]>,
|
||||
InstrItinData<PSEUDO , [InstrStage<1, [LUNIT, LSUNIT, MUNIT, SUNIT]>]>
|
||||
]>;
|
||||
|
||||
ProcessorItineraries<[LUNIT, LSUNIT, MUNIT, SUNIT], [], [
|
||||
InstrItinData<ALU32 , [InstrStage<1, [LUNIT, LSUNIT, MUNIT, SUNIT]>]>,
|
||||
InstrItinData<ALU64 , [InstrStage<1, [MUNIT, SUNIT]>]>,
|
||||
InstrItinData<CR , [InstrStage<1, [SUNIT]>]>,
|
||||
InstrItinData<J , [InstrStage<1, [SUNIT, MUNIT]>]>,
|
||||
InstrItinData<JR , [InstrStage<1, [MUNIT]>]>,
|
||||
InstrItinData<LD , [InstrStage<1, [LUNIT, LSUNIT]>]>,
|
||||
InstrItinData<M , [InstrStage<1, [MUNIT, SUNIT]>]>,
|
||||
InstrItinData<ST , [InstrStage<1, [LSUNIT]>]>,
|
||||
InstrItinData<S , [InstrStage<1, [SUNIT, MUNIT]>]>,
|
||||
InstrItinData<SYS , [InstrStage<1, [LSUNIT]>]>,
|
||||
InstrItinData<MARKER , [InstrStage<1, [LUNIT, LSUNIT, MUNIT, SUNIT]>]>,
|
||||
InstrItinData<PSEUDO , [InstrStage<1, [LUNIT, LSUNIT, MUNIT, SUNIT]>]>
|
||||
]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// V4 Machine Info +
|
||||
|
@ -23,7 +23,6 @@
|
||||
// | SLOT3 | XTYPE ALU32 J CR |
|
||||
// |===========|==================================================|
|
||||
|
||||
|
||||
// Functional Units.
|
||||
def SLOT0 : FuncUnit;
|
||||
def SLOT1 : FuncUnit;
|
||||
@ -34,22 +33,26 @@ def SLOT3 : FuncUnit;
|
||||
def NV_V4 : InstrItinClass;
|
||||
def MEM_V4 : InstrItinClass;
|
||||
// ALU64/M/S Instruction classes of V2 are collectively knownn as XTYPE in V4.
|
||||
def PREFIX : InstrItinClass;
|
||||
|
||||
def HexagonItinerariesV4 : ProcessorItineraries<
|
||||
[SLOT0, SLOT1, SLOT2, SLOT3], [], [
|
||||
InstrItinData<LD , [InstrStage<1, [SLOT0, SLOT1]>]>,
|
||||
InstrItinData<ST , [InstrStage<1, [SLOT0, SLOT1]>]>,
|
||||
InstrItinData<ALU32 , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,
|
||||
InstrItinData<NV_V4 , [InstrStage<1, [SLOT0]>]>,
|
||||
InstrItinData<MEM_V4 , [InstrStage<1, [SLOT0]>]>,
|
||||
InstrItinData<J , [InstrStage<1, [SLOT2, SLOT3]>]>,
|
||||
InstrItinData<JR , [InstrStage<1, [SLOT2]>]>,
|
||||
InstrItinData<CR , [InstrStage<1, [SLOT3]>]>,
|
||||
InstrItinData<PSEUDO , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,
|
||||
InstrItinData<ALU64 , [InstrStage<1, [SLOT2, SLOT3]>]>,
|
||||
InstrItinData<M , [InstrStage<1, [SLOT2, SLOT3]>]>,
|
||||
InstrItinData<S , [InstrStage<1, [SLOT2, SLOT3]>]>
|
||||
]>;
|
||||
def HexagonItinerariesV4 :
|
||||
ProcessorItineraries<[SLOT0, SLOT1, SLOT2, SLOT3], [], [
|
||||
InstrItinData<ALU32 , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,
|
||||
InstrItinData<ALU64 , [InstrStage<1, [SLOT2, SLOT3]>]>,
|
||||
InstrItinData<CR , [InstrStage<1, [SLOT3]>]>,
|
||||
InstrItinData<J , [InstrStage<1, [SLOT2, SLOT3]>]>,
|
||||
InstrItinData<JR , [InstrStage<1, [SLOT2]>]>,
|
||||
InstrItinData<LD , [InstrStage<1, [SLOT0, SLOT1]>]>,
|
||||
InstrItinData<M , [InstrStage<1, [SLOT2, SLOT3]>]>,
|
||||
InstrItinData<ST , [InstrStage<1, [SLOT0, SLOT1]>]>,
|
||||
InstrItinData<S , [InstrStage<1, [SLOT2, SLOT3]>]>,
|
||||
InstrItinData<SYS , [InstrStage<1, [SLOT0]>]>,
|
||||
InstrItinData<NV_V4 , [InstrStage<1, [SLOT0]>]>,
|
||||
InstrItinData<MEM_V4 , [InstrStage<1, [SLOT0]>]>,
|
||||
InstrItinData<MARKER , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,
|
||||
InstrItinData<PREFIX , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>,
|
||||
InstrItinData<PSEUDO , [InstrStage<1, [SLOT0, SLOT1, SLOT2, SLOT3]>]>
|
||||
]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Hexagon V4 Resource Definitions -
|
||||
|
@ -138,5 +138,8 @@ bool HexagonPassConfig::addPreEmitPass() {
|
||||
// Split up TFRcondsets into conditional transfers.
|
||||
PM.add(createHexagonSplitTFRCondSets(getHexagonTargetMachine()));
|
||||
|
||||
// Create Packets.
|
||||
PM.add(createHexagonPacketizer());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
3654
lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
Normal file
3654
lib/Target/Hexagon/HexagonVLIWPacketizer.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -15,6 +15,7 @@
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonAsmPrinter.h"
|
||||
#include "HexagonInstPrinter.h"
|
||||
#include "HexagonMCInst.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
@ -37,20 +38,50 @@ StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const {
|
||||
|
||||
void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
|
||||
StringRef Annot) {
|
||||
printInst((const HexagonMCInst*)(MI), O, Annot);
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printInst(const HexagonMCInst *MI, raw_ostream &O,
|
||||
StringRef Annot) {
|
||||
const char packetPadding[] = " ";
|
||||
const char startPacket = '{',
|
||||
endPacket = '}';
|
||||
// TODO: add outer HW loop when it's supported too.
|
||||
if (MI->getOpcode() == Hexagon::ENDLOOP0) {
|
||||
MCInst Nop;
|
||||
// Ending a harware loop is different from ending an regular packet.
|
||||
assert(MI->isEndPacket() && "Loop end must also end the packet");
|
||||
|
||||
O << packetPadding << startPacket << '\n';
|
||||
Nop.setOpcode(Hexagon::NOP);
|
||||
printInstruction(&Nop, O);
|
||||
O << packetPadding << endPacket;
|
||||
if (MI->isStartPacket()) {
|
||||
// There must be a packet to end a loop.
|
||||
// FIXME: when shuffling is always run, this shouldn't be needed.
|
||||
HexagonMCInst Nop;
|
||||
StringRef NoAnnot;
|
||||
|
||||
Nop.setOpcode (Hexagon::NOP);
|
||||
Nop.setStartPacket (MI->isStartPacket());
|
||||
printInst (&Nop, O, NoAnnot);
|
||||
}
|
||||
|
||||
// Close the packet.
|
||||
if (MI->isEndPacket())
|
||||
O << packetPadding << endPacket;
|
||||
|
||||
printInstruction(MI, O);
|
||||
}
|
||||
else {
|
||||
// Prefix the insn opening the packet.
|
||||
if (MI->isStartPacket())
|
||||
O << packetPadding << startPacket << '\n';
|
||||
|
||||
printInstruction(MI, O);
|
||||
|
||||
// Suffix the insn closing the packet.
|
||||
if (MI->isEndPacket())
|
||||
// Suffix the packet in a new line always, since the GNU assembler has
|
||||
// issues with a closing brace on the same line as CONST{32,64}.
|
||||
O << '\n' << packetPadding << endPacket;
|
||||
}
|
||||
|
||||
printInstruction(MI, O);
|
||||
printAnnotation(O, Annot);
|
||||
}
|
||||
|
||||
@ -69,18 +100,18 @@ void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
|
||||
}
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printImmOperand
|
||||
(const MCInst *MI, unsigned OpNo, raw_ostream &O) const {
|
||||
void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
O << MI->getOperand(OpNo).getImm();
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
raw_ostream &O) const {
|
||||
O << MI->getOperand(OpNo).getImm();
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printUnsignedImmOperand
|
||||
(const MCInst *MI, unsigned OpNo, raw_ostream &O) const {
|
||||
void HexagonInstPrinter::printUnsignedImmOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
O << MI->getOperand(OpNo).getImm();
|
||||
}
|
||||
|
||||
@ -89,13 +120,13 @@ void HexagonInstPrinter::printNegImmOperand(const MCInst *MI, unsigned OpNo,
|
||||
O << -MI->getOperand(OpNo).getImm();
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printNOneImmOperand
|
||||
(const MCInst *MI, unsigned OpNo, raw_ostream &O) const {
|
||||
void HexagonInstPrinter::printNOneImmOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
O << -1;
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printMEMriOperand
|
||||
(const MCInst *MI, unsigned OpNo, raw_ostream &O) const {
|
||||
void HexagonInstPrinter::printMEMriOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
const MCOperand& MO0 = MI->getOperand(OpNo);
|
||||
const MCOperand& MO1 = MI->getOperand(OpNo + 1);
|
||||
|
||||
@ -103,8 +134,8 @@ void HexagonInstPrinter::printMEMriOperand
|
||||
O << " + #" << MO1.getImm();
|
||||
}
|
||||
|
||||
void HexagonInstPrinter::printFrameIndexOperand
|
||||
(const MCInst *MI, unsigned OpNo, raw_ostream &O) const {
|
||||
void HexagonInstPrinter::printFrameIndexOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) const {
|
||||
const MCOperand& MO0 = MI->getOperand(OpNo);
|
||||
const MCOperand& MO1 = MI->getOperand(OpNo + 1);
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#ifndef HEXAGONINSTPRINTER_H
|
||||
#define HEXAGONINSTPRINTER_H
|
||||
|
||||
#include "HexagonMCInst.h"
|
||||
#include "llvm/MC/MCInstPrinter.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -25,6 +26,7 @@ namespace llvm {
|
||||
: MCInstPrinter(MAI, MII, MRI) {}
|
||||
|
||||
virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot);
|
||||
void printInst(const HexagonMCInst *MI, raw_ostream &O, StringRef Annot);
|
||||
virtual StringRef getOpcodeName(unsigned Opcode) const;
|
||||
void printInstruction(const MCInst *MI, raw_ostream &O);
|
||||
StringRef getRegName(unsigned RegNo) const;
|
||||
|
@ -23,14 +23,41 @@ namespace llvm {
|
||||
/// instruction info tracks.
|
||||
///
|
||||
namespace HexagonII {
|
||||
|
||||
// *** The code below must match HexagonInstrFormat*.td *** //
|
||||
|
||||
// Insn types.
|
||||
// *** Must match HexagonInstrFormat*.td ***
|
||||
enum Type {
|
||||
TypePSEUDO = 0,
|
||||
TypeALU32 = 1,
|
||||
TypeCR = 2,
|
||||
TypeJR = 3,
|
||||
TypeJ = 4,
|
||||
TypeLD = 5,
|
||||
TypeST = 6,
|
||||
TypeSYSTEM = 7,
|
||||
TypeXTYPE = 8,
|
||||
TypeMEMOP = 9,
|
||||
TypeNV = 10,
|
||||
TypePREFIX = 30, // Such as extenders.
|
||||
TypeMARKER = 31 // Such as end of a HW loop.
|
||||
};
|
||||
|
||||
|
||||
|
||||
// MCInstrDesc TSFlags
|
||||
// *** Must match HexagonInstrFormat*.td ***
|
||||
enum {
|
||||
// This 5-bit field describes the insn type.
|
||||
TypePos = 0,
|
||||
TypeMask = 0x1f,
|
||||
|
||||
// Solo instructions.
|
||||
SoloPos = 5,
|
||||
SoloMask = 0x1,
|
||||
|
||||
// Predicated instructions.
|
||||
PredicatedPos = 1,
|
||||
PredicatedPos = 6,
|
||||
PredicatedMask = 0x1
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user