mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-24 22:24:54 +00:00
Add support to model pipeline bypass / forwarding.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115005 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -22,6 +22,14 @@
|
|||||||
//
|
//
|
||||||
class FuncUnit;
|
class FuncUnit;
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Pipeline bypass / forwarding - These values specifies the symbolic names of
|
||||||
|
// pipeline bypasses which can be used to forward results of instructions
|
||||||
|
// that are forwarded to uses.
|
||||||
|
class Bypass;
|
||||||
|
|
||||||
|
def NoBypass : Bypass;
|
||||||
|
|
||||||
class ReservationKind<bits<1> val> {
|
class ReservationKind<bits<1> val> {
|
||||||
int Value = val;
|
int Value = val;
|
||||||
}
|
}
|
||||||
@@ -81,22 +89,26 @@ def NoItinerary : InstrItinClass;
|
|||||||
// instruction itinerary class (name) to its itinerary data.
|
// instruction itinerary class (name) to its itinerary data.
|
||||||
//
|
//
|
||||||
class InstrItinData<InstrItinClass Class, list<InstrStage> stages,
|
class InstrItinData<InstrItinClass Class, list<InstrStage> stages,
|
||||||
list<int> operandcycles = []> {
|
list<int> operandcycles = [],
|
||||||
|
list<Bypass> bypasses = []> {
|
||||||
InstrItinClass TheClass = Class;
|
InstrItinClass TheClass = Class;
|
||||||
list<InstrStage> Stages = stages;
|
list<InstrStage> Stages = stages;
|
||||||
list<int> OperandCycles = operandcycles;
|
list<int> OperandCycles = operandcycles;
|
||||||
|
list<Bypass> Bypasses = bypasses;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Processor itineraries - These values represent the set of all itinerary
|
// Processor itineraries - These values represent the set of all itinerary
|
||||||
// classes for a given chip set.
|
// classes for a given chip set.
|
||||||
//
|
//
|
||||||
class ProcessorItineraries<list<FuncUnit> fu, list<InstrItinData> iid> {
|
class ProcessorItineraries<list<FuncUnit> fu, list<Bypass> bp,
|
||||||
|
list<InstrItinData> iid> {
|
||||||
list<FuncUnit> FU = fu;
|
list<FuncUnit> FU = fu;
|
||||||
|
list<Bypass> BP = bp;
|
||||||
list<InstrItinData> IID = iid;
|
list<InstrItinData> IID = iid;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NoItineraries - A marker that can be used by processors without schedule
|
// NoItineraries - A marker that can be used by processors without schedule
|
||||||
// info.
|
// info.
|
||||||
def NoItineraries : ProcessorItineraries<[], []>;
|
def NoItineraries : ProcessorItineraries<[], [], []>;
|
||||||
|
|
||||||
|
@@ -156,7 +156,7 @@ def IIC_VTBX4 : InstrItinClass;
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Processor instruction itineraries.
|
// Processor instruction itineraries.
|
||||||
|
|
||||||
def GenericItineraries : ProcessorItineraries<[], []>;
|
def GenericItineraries : ProcessorItineraries<[], [], []>;
|
||||||
|
|
||||||
include "ARMScheduleV6.td"
|
include "ARMScheduleV6.td"
|
||||||
include "ARMScheduleA8.td"
|
include "ARMScheduleA8.td"
|
||||||
|
@@ -25,7 +25,8 @@ def A8_NLSPipe : FuncUnit; // NEON LS pipe
|
|||||||
// Dual issue pipeline represented by A8_Pipe0 | A8_Pipe1
|
// Dual issue pipeline represented by A8_Pipe0 | A8_Pipe1
|
||||||
//
|
//
|
||||||
def CortexA8Itineraries : ProcessorItineraries<
|
def CortexA8Itineraries : ProcessorItineraries<
|
||||||
[A8_Issue, A8_Pipe0, A8_Pipe1, A8_LdSt0, A8_LdSt1, A8_NPipe, A8_NLSPipe], [
|
[A8_Issue, A8_Pipe0, A8_Pipe1, A8_LdSt0, A8_LdSt1, A8_NPipe, A8_NLSPipe],
|
||||||
|
[], [
|
||||||
// Two fully-pipelined integer ALU pipelines
|
// Two fully-pipelined integer ALU pipelines
|
||||||
//
|
//
|
||||||
// No operand cycles
|
// No operand cycles
|
||||||
|
@@ -26,7 +26,7 @@ def A9_DRegsN : FuncUnit; // FP register set, NEON side
|
|||||||
// Dual issue pipeline represented by A9_Pipe0 | A9_Pipe1
|
// Dual issue pipeline represented by A9_Pipe0 | A9_Pipe1
|
||||||
//
|
//
|
||||||
def CortexA9Itineraries : ProcessorItineraries<
|
def CortexA9Itineraries : ProcessorItineraries<
|
||||||
[A9_NPipe, A9_DRegsN, A9_DRegsVFP, A9_LSPipe, A9_Pipe0, A9_Pipe1], [
|
[A9_NPipe, A9_DRegsN, A9_DRegsVFP, A9_LSPipe, A9_Pipe0, A9_Pipe1], [], [
|
||||||
// Two fully-pipelined integer ALU pipelines
|
// Two fully-pipelined integer ALU pipelines
|
||||||
// FIXME: There are no operand latencies for these instructions at all!
|
// FIXME: There are no operand latencies for these instructions at all!
|
||||||
//
|
//
|
||||||
|
@@ -19,7 +19,7 @@ def V6_Pipe : FuncUnit; // pipeline
|
|||||||
// Scheduling information derived from "ARM1176JZF-S Technical Reference Manual"
|
// Scheduling information derived from "ARM1176JZF-S Technical Reference Manual"
|
||||||
//
|
//
|
||||||
def ARMV6Itineraries : ProcessorItineraries<
|
def ARMV6Itineraries : ProcessorItineraries<
|
||||||
[V6_Pipe], [
|
[V6_Pipe], [], [
|
||||||
//
|
//
|
||||||
// No operand cycles
|
// No operand cycles
|
||||||
InstrItinData<IIC_iALUx , [InstrStage<1, [V6_Pipe]>]>,
|
InstrItinData<IIC_iALUx , [InstrStage<1, [V6_Pipe]>]>,
|
||||||
|
@@ -54,7 +54,7 @@ def s_pseudo : InstrItinClass;
|
|||||||
//modified some
|
//modified some
|
||||||
|
|
||||||
def Alpha21264Itineraries : ProcessorItineraries<
|
def Alpha21264Itineraries : ProcessorItineraries<
|
||||||
[L0, L1, FST0, FST1, U0, U1, FA, FM], [
|
[L0, L1, FST0, FST1, U0, U1, FA, FM], [], [
|
||||||
InstrItinData<s_ild , [InstrStage<3, [L0, L1]>]>,
|
InstrItinData<s_ild , [InstrStage<3, [L0, L1]>]>,
|
||||||
InstrItinData<s_fld , [InstrStage<4, [L0, L1]>]>,
|
InstrItinData<s_fld , [InstrStage<4, [L0, L1]>]>,
|
||||||
InstrItinData<s_ist , [InstrStage<0, [L0, L1]>]>,
|
InstrItinData<s_ist , [InstrStage<0, [L0, L1]>]>,
|
||||||
|
@@ -36,7 +36,7 @@ def RotateShift : InstrItinClass; // EVEN_UNIT
|
|||||||
def ImmLoad : InstrItinClass; // EVEN_UNIT
|
def ImmLoad : InstrItinClass; // EVEN_UNIT
|
||||||
|
|
||||||
/* Note: The itinerary for the Cell SPU is somewhat contrived... */
|
/* Note: The itinerary for the Cell SPU is somewhat contrived... */
|
||||||
def SPUItineraries : ProcessorItineraries<[ODD_UNIT, EVEN_UNIT], [
|
def SPUItineraries : ProcessorItineraries<[ODD_UNIT, EVEN_UNIT], [], [
|
||||||
InstrItinData<LoadStore , [InstrStage<6, [ODD_UNIT]>]>,
|
InstrItinData<LoadStore , [InstrStage<6, [ODD_UNIT]>]>,
|
||||||
InstrItinData<BranchHints , [InstrStage<6, [ODD_UNIT]>]>,
|
InstrItinData<BranchHints , [InstrStage<6, [ODD_UNIT]>]>,
|
||||||
InstrItinData<BranchResolv, [InstrStage<4, [ODD_UNIT]>]>,
|
InstrItinData<BranchResolv, [InstrStage<4, [ODD_UNIT]>]>,
|
||||||
|
@@ -41,7 +41,7 @@ def IIPseudo : InstrItinClass;
|
|||||||
// MBlaze Generic instruction itineraries.
|
// MBlaze Generic instruction itineraries.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
def MBlazeGenericItineraries : ProcessorItineraries<
|
def MBlazeGenericItineraries : ProcessorItineraries<
|
||||||
[ALU, IMULDIV], [
|
[ALU, IMULDIV], [], [
|
||||||
InstrItinData<IIAlu , [InstrStage<1, [ALU]>]>,
|
InstrItinData<IIAlu , [InstrStage<1, [ALU]>]>,
|
||||||
InstrItinData<IILoad , [InstrStage<3, [ALU]>]>,
|
InstrItinData<IILoad , [InstrStage<3, [ALU]>]>,
|
||||||
InstrItinData<IIStore , [InstrStage<1, [ALU]>]>,
|
InstrItinData<IIStore , [InstrStage<1, [ALU]>]>,
|
||||||
|
@@ -40,7 +40,7 @@ def IIPseudo : InstrItinClass;
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Mips Generic instruction itineraries.
|
// Mips Generic instruction itineraries.
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [
|
def MipsGenericItineraries : ProcessorItineraries<[ALU, IMULDIV], [], [
|
||||||
InstrItinData<IIAlu , [InstrStage<1, [ALU]>]>,
|
InstrItinData<IIAlu , [InstrStage<1, [ALU]>]>,
|
||||||
InstrItinData<IILoad , [InstrStage<3, [ALU]>]>,
|
InstrItinData<IILoad , [InstrStage<3, [ALU]>]>,
|
||||||
InstrItinData<IIStore , [InstrStage<1, [ALU]>]>,
|
InstrItinData<IIStore , [InstrStage<1, [ALU]>]>,
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
|
|
||||||
def G3Itineraries : ProcessorItineraries<
|
def G3Itineraries : ProcessorItineraries<
|
||||||
[IU1, IU2, FPU1, BPU, SRU, SLU], [
|
[IU1, IU2, FPU1, BPU, SRU, SLU], [], [
|
||||||
InstrItinData<IntGeneral , [InstrStage<1, [IU1, IU2]>]>,
|
InstrItinData<IntGeneral , [InstrStage<1, [IU1, IU2]>]>,
|
||||||
InstrItinData<IntCompare , [InstrStage<1, [IU1, IU2]>]>,
|
InstrItinData<IntCompare , [InstrStage<1, [IU1, IU2]>]>,
|
||||||
InstrItinData<IntDivW , [InstrStage<19, [IU1]>]>,
|
InstrItinData<IntDivW , [InstrStage<19, [IU1]>]>,
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
def G4Itineraries : ProcessorItineraries<
|
def G4Itineraries : ProcessorItineraries<
|
||||||
[IU1, IU2, SLU, SRU, BPU, FPU1, VIU1, VIU2, VPU, VFPU], [
|
[IU1, IU2, SLU, SRU, BPU, FPU1, VIU1, VIU2, VPU, VFPU], [], [
|
||||||
InstrItinData<IntGeneral , [InstrStage<1, [IU1, IU2]>]>,
|
InstrItinData<IntGeneral , [InstrStage<1, [IU1, IU2]>]>,
|
||||||
InstrItinData<IntCompare , [InstrStage<1, [IU1, IU2]>]>,
|
InstrItinData<IntCompare , [InstrStage<1, [IU1, IU2]>]>,
|
||||||
InstrItinData<IntDivW , [InstrStage<19, [IU1]>]>,
|
InstrItinData<IntDivW , [InstrStage<19, [IU1]>]>,
|
||||||
|
@@ -15,7 +15,7 @@ def IU3 : FuncUnit; // integer unit 3 (7450 simple)
|
|||||||
def IU4 : FuncUnit; // integer unit 4 (7450 simple)
|
def IU4 : FuncUnit; // integer unit 4 (7450 simple)
|
||||||
|
|
||||||
def G4PlusItineraries : ProcessorItineraries<
|
def G4PlusItineraries : ProcessorItineraries<
|
||||||
[IU1, IU2, IU3, IU4, BPU, SLU, FPU1, VFPU, VIU1, VIU2, VPU], [
|
[IU1, IU2, IU3, IU4, BPU, SLU, FPU1, VFPU, VIU1, VIU2, VPU], [], [
|
||||||
InstrItinData<IntGeneral , [InstrStage<1, [IU1, IU2, IU3, IU4]>]>,
|
InstrItinData<IntGeneral , [InstrStage<1, [IU1, IU2, IU3, IU4]>]>,
|
||||||
InstrItinData<IntCompare , [InstrStage<1, [IU1, IU2, IU3, IU4]>]>,
|
InstrItinData<IntCompare , [InstrStage<1, [IU1, IU2, IU3, IU4]>]>,
|
||||||
InstrItinData<IntDivW , [InstrStage<23, [IU2]>]>,
|
InstrItinData<IntDivW , [InstrStage<23, [IU2]>]>,
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
def G5Itineraries : ProcessorItineraries<
|
def G5Itineraries : ProcessorItineraries<
|
||||||
[IU1, IU2, SLU, BPU, FPU1, FPU2, VFPU, VIU1, VIU2, VPU], [
|
[IU1, IU2, SLU, BPU, FPU1, FPU2, VFPU, VIU1, VIU2, VPU], [], [
|
||||||
InstrItinData<IntGeneral , [InstrStage<2, [IU1, IU2]>]>,
|
InstrItinData<IntGeneral , [InstrStage<2, [IU1, IU2]>]>,
|
||||||
InstrItinData<IntCompare , [InstrStage<3, [IU1, IU2]>]>,
|
InstrItinData<IntCompare , [InstrStage<3, [IU1, IU2]>]>,
|
||||||
InstrItinData<IntDivD , [InstrStage<68, [IU1]>]>,
|
InstrItinData<IntDivD , [InstrStage<68, [IU1]>]>,
|
||||||
|
@@ -262,6 +262,24 @@ void SubtargetEmitter::FormItineraryOperandCycleString(Record *ItinData,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SubtargetEmitter::FormItineraryBypassString(const std::string &Name,
|
||||||
|
Record *ItinData,
|
||||||
|
std::string &ItinString,
|
||||||
|
unsigned NOperandCycles) {
|
||||||
|
const std::vector<Record*> &BypassList =
|
||||||
|
ItinData->getValueAsListOfDefs("Bypasses");
|
||||||
|
unsigned N = BypassList.size();
|
||||||
|
for (unsigned i = 0; i < N;) {
|
||||||
|
ItinString += Name + "Bypass::" + BypassList[i]->getName();
|
||||||
|
if (++i < N) ItinString += ", ";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; N < NOperandCycles;) {
|
||||||
|
ItinString += " 0";
|
||||||
|
if (++N < NOperandCycles) ItinString += ", ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// EmitStageAndOperandCycleData - Generate unique itinerary stages and
|
// EmitStageAndOperandCycleData - Generate unique itinerary stages and
|
||||||
// operand cycle tables. Record itineraries for processors.
|
// operand cycle tables. Record itineraries for processors.
|
||||||
@@ -296,6 +314,16 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
|
|||||||
<< " = 1 << " << j << ";\n";
|
<< " = 1 << " << j << ";\n";
|
||||||
|
|
||||||
OS << "}\n";
|
OS << "}\n";
|
||||||
|
|
||||||
|
std::vector<Record*> BPs = Proc->getValueAsListOfDefs("BP");
|
||||||
|
OS << "\n// Pipeline bypasses for itineraries \"" << Name << "\"\n"
|
||||||
|
<< "namespace " << Name << "Bypass {\n";
|
||||||
|
|
||||||
|
for (unsigned j = 0, BPN = BPs.size(); j < BPN; ++j)
|
||||||
|
OS << " const unsigned " << BPs[j]->getName()
|
||||||
|
<< " = 1 << " << j << ";\n";
|
||||||
|
|
||||||
|
OS << "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Begin stages table
|
// Begin stages table
|
||||||
@@ -305,6 +333,10 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
|
|||||||
// Begin operand cycle table
|
// Begin operand cycle table
|
||||||
std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n";
|
std::string OperandCycleTable = "static const unsigned OperandCycles[] = {\n";
|
||||||
OperandCycleTable += " 0, // No itinerary\n";
|
OperandCycleTable += " 0, // No itinerary\n";
|
||||||
|
|
||||||
|
// Begin pipeline bypass table
|
||||||
|
std::string BypassTable = "static const unsigned Bypasses[] = {\n";
|
||||||
|
BypassTable += " 0, // No itinerary\n";
|
||||||
|
|
||||||
unsigned StageCount = 1, OperandCycleCount = 1;
|
unsigned StageCount = 1, OperandCycleCount = 1;
|
||||||
unsigned ItinStageEnum = 1, ItinOperandCycleEnum = 1;
|
unsigned ItinStageEnum = 1, ItinOperandCycleEnum = 1;
|
||||||
@@ -342,6 +374,10 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
|
|||||||
FormItineraryOperandCycleString(ItinData, ItinOperandCycleString,
|
FormItineraryOperandCycleString(ItinData, ItinOperandCycleString,
|
||||||
NOperandCycles);
|
NOperandCycles);
|
||||||
|
|
||||||
|
std::string ItinBypassString;
|
||||||
|
FormItineraryBypassString(Name, ItinData, ItinBypassString,
|
||||||
|
NOperandCycles);
|
||||||
|
|
||||||
// Check to see if stage already exists and create if it doesn't
|
// Check to see if stage already exists and create if it doesn't
|
||||||
unsigned FindStage = 0;
|
unsigned FindStage = 0;
|
||||||
if (NStages > 0) {
|
if (NStages > 0) {
|
||||||
@@ -367,6 +403,11 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
|
|||||||
// Record Itin class number.
|
// Record Itin class number.
|
||||||
ItinOperandCycleMap[ItinOperandCycleString] =
|
ItinOperandCycleMap[ItinOperandCycleString] =
|
||||||
FindOperandCycle = OperandCycleCount;
|
FindOperandCycle = OperandCycleCount;
|
||||||
|
|
||||||
|
// Emit as bypass, // index
|
||||||
|
BypassTable += ItinBypassString + ", // " +
|
||||||
|
itostr(ItinOperandCycleEnum) + "\n";
|
||||||
|
|
||||||
OperandCycleCount += NOperandCycles;
|
OperandCycleCount += NOperandCycles;
|
||||||
ItinOperandCycleEnum++;
|
ItinOperandCycleEnum++;
|
||||||
}
|
}
|
||||||
@@ -389,7 +430,7 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
|
|||||||
// Add process itinerary to list
|
// Add process itinerary to list
|
||||||
ProcList.push_back(ItinList);
|
ProcList.push_back(ItinList);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Closing stage
|
// Closing stage
|
||||||
StageTable += " { 0, 0, 0, llvm::InstrStage::Required } // End itinerary\n";
|
StageTable += " { 0, 0, 0, llvm::InstrStage::Required } // End itinerary\n";
|
||||||
StageTable += "};\n";
|
StageTable += "};\n";
|
||||||
@@ -398,9 +439,13 @@ void SubtargetEmitter::EmitStageAndOperandCycleData(raw_ostream &OS,
|
|||||||
OperandCycleTable += " 0 // End itinerary\n";
|
OperandCycleTable += " 0 // End itinerary\n";
|
||||||
OperandCycleTable += "};\n";
|
OperandCycleTable += "};\n";
|
||||||
|
|
||||||
|
BypassTable += " 0 // End itinerary\n";
|
||||||
|
BypassTable += "};\n";
|
||||||
|
|
||||||
// Emit tables.
|
// Emit tables.
|
||||||
OS << StageTable;
|
OS << StageTable;
|
||||||
OS << OperandCycleTable;
|
OS << OperandCycleTable;
|
||||||
|
OS << BypassTable;
|
||||||
|
|
||||||
// Emit size of tables
|
// Emit size of tables
|
||||||
OS<<"\nenum {\n";
|
OS<<"\nenum {\n";
|
||||||
|
@@ -40,6 +40,9 @@ class SubtargetEmitter : public TableGenBackend {
|
|||||||
unsigned &NStages);
|
unsigned &NStages);
|
||||||
void FormItineraryOperandCycleString(Record *ItinData, std::string &ItinString,
|
void FormItineraryOperandCycleString(Record *ItinData, std::string &ItinString,
|
||||||
unsigned &NOperandCycles);
|
unsigned &NOperandCycles);
|
||||||
|
void FormItineraryBypassString(const std::string &Names,
|
||||||
|
Record *ItinData,
|
||||||
|
std::string &ItinString, unsigned NOperandCycles);
|
||||||
void EmitStageAndOperandCycleData(raw_ostream &OS, unsigned NItinClasses,
|
void EmitStageAndOperandCycleData(raw_ostream &OS, unsigned NItinClasses,
|
||||||
std::map<std::string, unsigned> &ItinClassesMap,
|
std::map<std::string, unsigned> &ItinClassesMap,
|
||||||
std::vector<Record*> &ItinClassList,
|
std::vector<Record*> &ItinClassList,
|
||||||
|
Reference in New Issue
Block a user