Index: llvm/lib/Target/SystemZ/SystemZHazardRecognizer.h =================================================================== --- llvm/lib/Target/SystemZ/SystemZHazardRecognizer.h +++ llvm/lib/Target/SystemZ/SystemZHazardRecognizer.h @@ -45,6 +45,8 @@ class SystemZHazardRecognizer : public ScheduleHazardRecognizer { const SystemZInstrInfo *TII; + std::string getSideSteerResourceName(unsigned ID) const; + const TargetRegisterInfo *TRI; const TargetSchedModel *SchedModel; /// Keep track of the number of decoder slots used in the current @@ -88,6 +90,44 @@ /// when a stalling operation is scheduled (which uses the FPd resource). unsigned LastFPdOpCycleIdx; + // There is no enum list generated for the processor resources by tablegen, + // so make one here for the needed ones. + enum ProcRes { B2BRW = 1, B2BRn = 2, B2BnW = 3, LSU = 6 }; + bool usesProcRes(SUnit *SU, ProcRes ProcResIdx) const; + bool readsB2BVector(SUnit *SU) const { + return usesProcRes(SU, ProcRes::B2BRW) || usesProcRes(SU, ProcRes::B2BRn); + } + bool writesB2BVector(SUnit *SU) const { + return usesProcRes(SU, ProcRes::B2BRW) || usesProcRes(SU, ProcRes::B2BnW); + } + bool isB2BOpIdx(SUnit *SU, unsigned Idx, bool Def) const; + bool isB2BOpReg(SUnit *SU, Register Reg, bool Def) const; + bool isB2BEdge(SUnit *SU, SUnit *SuccSU, Register Reg) const; + bool hasB2BEdge(SUnit *SU, SUnit *SuccSU) const; + bool isCountedProcResource(unsigned PIdx) const { + return !(PIdx == ProcRes::B2BRW || PIdx == ProcRes::B2BRn || + PIdx == ProcRes::B2BnW); + } + + std::map B2BWSides; + bool willGoLeft(SUnit *SU) const { return getCurrCycleIdx(SU) < 3; } + bool wasScheduledLeft(SUnit *SU) const { + std::map::const_iterator I = B2BWSides.find(SU); + assert(I != B2BWSides.end() && "SU not scheduled?"); + return I->second; + } + bool isAvailable(SUnit *SU, SUnit *EvalSU = nullptr) const; + bool checkB2BUser(SUnit *Candidate, SUnit *User, Register Reg, + SUnit *&OtherPred) const; + struct B2BWriteMetrics { + unsigned NumReaders; + unsigned NumReadersWithMiddlePred; + B2BWriteMetrics() : NumReaders(0), NumReadersWithMiddlePred(0) {} + }; + + int analyzeB2BWrite(B2BWriteMetrics &M, unsigned CurrSlot); + void B2BWriteCost(SUnit *SU, B2BWriteMetrics &M) const; + /// A counter of decoder groups scheduled. unsigned GrpCount; @@ -108,9 +148,25 @@ public: SystemZHazardRecognizer(const SystemZInstrInfo *tii, + const TargetRegisterInfo *tri, const TargetSchedModel *SM) - : TII(tii), SchedModel(SM) { + : TII(tii), TRI(tri), SchedModel(SM) { Reset(); + +#ifndef NDEBUG + const MCProcResourceDesc *PRD = SchedModel->getProcResource(ProcRes::B2BRW); + assert(std::string(PRD->Name).find("B2BRW") != std::string::npos && + "Bad ProcRes enum mapping"); + PRD = SchedModel->getProcResource(ProcRes::B2BRn); + assert(std::string(PRD->Name).find("B2BRn") != std::string::npos && + "Bad ProcRes enum mapping"); + PRD = SchedModel->getProcResource(ProcRes::B2BnW); + assert(std::string(PRD->Name).find("B2BnW") != std::string::npos && + "Bad ProcRes enum mapping"); + PRD = SchedModel->getProcResource(ProcRes::LSU); + assert(std::string(PRD->Name).find("LSU") != std::string::npos && + "Bad ProcRes enum mapping"); +#endif } HazardType getHazardType(SUnit *SU, int Stalls = 0) override; @@ -141,6 +197,11 @@ /// a negative value means it would be good to schedule SU next. int resourcesCost(SUnit *SU); + int B2BCost(SUnit *SU); + void B2BReadCost(SUnit *SU, unsigned &NumGood, unsigned &NumBad, + bool FlipSide = false) const; + void clearSUMappings() { B2BWSides.clear(); } + #ifndef NDEBUG // Debug dumping. std::string CurGroupDbg; // current group as text Index: llvm/lib/Target/SystemZ/SystemZHazardRecognizer.cpp =================================================================== --- llvm/lib/Target/SystemZ/SystemZHazardRecognizer.cpp +++ llvm/lib/Target/SystemZ/SystemZHazardRecognizer.cpp @@ -42,6 +42,10 @@ "resources during scheduling."), cl::init(8)); +// EXPERIMENTAL +#include "llvm/Support/CommandLine.h" +static cl::opt DUMP_B2B("dump-b2b", cl::init(false)); + unsigned SystemZHazardRecognizer:: getNumDecoderSlots(SUnit *SU) const { const MCSchedClassDesc *SC = getSchedClass(SU); @@ -73,6 +77,174 @@ return Idx; } +static bool isFXUReg(Register Reg) { + return (SystemZ::GRX32BitRegClass.contains(Reg) || + SystemZ::GR64BitRegClass.contains(Reg) || + SystemZ::GR128BitRegClass.contains(Reg)); +} + +static bool isFXUReg(const MachineOperand &MO) { return isFXUReg(MO.getReg()); } + +bool SystemZHazardRecognizer::usesProcRes(SUnit *SU, ProcRes ProcResIdx) const { + const MCSchedClassDesc *SC = getSchedClass(SU); + if (!SC->isValid()) + return false; + for (TargetSchedModel::ProcResIter + PI = SchedModel->getWriteProcResBegin(SC), + PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI) + if (PI->ProcResourceIdx == ProcResIdx) + return true; + return false; +} + +bool SystemZHazardRecognizer:: +isB2BOpIdx(SUnit *SU, unsigned Idx, bool Def) const { + MachineInstr *MI = SU->getInstr(); + // A memory operand handled by the LSU is not back-to-back. + const MCInstrDesc &MCID = MI->getDesc(); + if (Idx >= MCID.getNumOperands()) + return false; + if (MCID.OpInfo[Idx].OperandType == MCOI::OPERAND_MEMORY && + usesProcRes(SU, ProcRes::LSU)) + return false; + + const MachineOperand &MO = MI->getOperand(Idx); + if (!MO.isReg() || !MO.getReg() || MO.isImplicit() || Def != MO.isDef() || + !isFXUReg(MO)) + return false; + return ((!Def && readsB2BVector(SU)) || (Def && writesB2BVector(SU))); +} + +bool SystemZHazardRecognizer:: +isB2BOpReg(SUnit *SU, Register Reg, bool Def) const { + MachineInstr *MI = SU->getInstr(); + for (unsigned Idx = 0; Idx < MI->getNumExplicitOperands(); ++Idx) { + MachineOperand &MO = MI->getOperand(Idx); + if (MO.isReg() && + ((Def && TRI->regsOverlap(MO.getReg(), Reg)) || + (!Def && MO.getReg() == Reg)) && + isB2BOpIdx(SU, Idx, Def)) + return true; + } + return false; +} + +bool SystemZHazardRecognizer:: +isB2BEdge(SUnit *SU, SUnit *SuccSU, Register Reg) const { + // Check the difference in height in order to ignore cases which are not on the CP. + // TODO: Try to check reachablility instead? Then a slightly lower but + // independent user could also perhaps be B2B...? + unsigned HeightDiff = SU->getHeight() - SuccSU->getHeight(); + return (HeightDiff <= SU->Latency && // Might be less due to read-advance. + isB2BOpReg(SU, Reg, true/*Def*/) && + isB2BOpReg(SuccSU, Reg, false/*Def*/)); +} + +bool SystemZHazardRecognizer::hasB2BEdge(SUnit *SU, SUnit *SuccSU) const { + for (SDep &SuccDep : SU->Succs) + if (SuccDep.getKind() == SDep::Data && SuccDep.getSUnit() == SuccSU && + isB2BEdge(SU, SuccSU, SuccDep.getReg())) + return true; + return false; +} + +bool SystemZHazardRecognizer::isAvailable(SUnit *SU, SUnit *EvalSU) const { + for (SDep &Pred : SU->Preds) { + SUnit *P = Pred.getSUnit(); + if (!P->isBoundaryNode() && !P->isScheduled && P != EvalSU) + return false; + } + return true; +} + +bool SystemZHazardRecognizer:: +checkB2BUser(SUnit *Candidate, SUnit *User, Register Reg, + SUnit *&OtherPred) const { + if (getSchedClass(User)->BeginGroup) + return false; + + OtherPred = nullptr; + for (SDep &Pred : User->Preds) { + SUnit *P = Pred.getSUnit(); + if (P->isBoundaryNode() || P == Candidate || P->isScheduled) + continue; + + // B2BW Candidate + // /\ /\ P2 + // \ \ + // \ OtherPred Scheduled Pred + // P \ /\ P .....: P + // \ / .......: + // B2BR User...: + // + // => [Candidate (OtherPred) User] (decoder group) + // Allow one other unscheduled predecessor than Candidate if it is + // available or only waiting for Candidate. + if (OtherPred) { + if (P != OtherPred) + return false; + continue; + } + if (getSchedClass(P)->NumMicroOps > 1) + return false; + OtherPred = P; + } + + return true; +} + +void SystemZHazardRecognizer::B2BWriteCost(SUnit *SU, B2BWriteMetrics &M) const { + // Give an immediate user a chance into the same decoder group. + SmallPtrSet Seen; + for (SDep &SuccDep : SU->Succs) { + SUnit *SuccSU = SuccDep.getSUnit(); + if (!SuccSU->isBoundaryNode() && SuccDep.getKind() == SDep::Data && + !Seen.count(SuccSU) && isB2BEdge(SU, SuccSU, SuccDep.getReg())) { + SUnit *OtherPred = nullptr; + if (!checkB2BUser(SU, SuccSU, SuccDep.getReg(), OtherPred)) + continue; + Seen.insert(SuccSU); + + if (OtherPred == nullptr) + M.NumReaders++; + else if (OtherPred != nullptr) { + if (isAvailable(OtherPred)) + M.NumReadersWithMiddlePred++; + } + } + } +} + +int SystemZHazardRecognizer:: +analyzeB2BWrite(B2BWriteMetrics &M, unsigned CurrSlot) { + // Give negative cost if user could be put in same group. The value + // reflects the relative order between the different cases. + + if (DUMP_B2B) + dbgs() << "++ B2B Writer: NumReaders:" << M.NumReaders + << " NumReadersWithMiddlePred:" << M.NumReadersWithMiddlePred << "\n"; + + // If there is a benefit, take it, or reject if better to wait. + if (CurrSlot == 0) { + if (M.NumReaders > 1) + return -2; + if (M.NumReadersWithMiddlePred) + return -2; + if (M.NumReaders == 1) + return -1; + } else if (CurrSlot == 1) { + if (M.NumReaders) + return -1; + if (M.NumReadersWithMiddlePred) + return 2; + } else { + assert(CurrSlot == 2); + if (M.NumReaders || M.NumReadersWithMiddlePred) + return 2; + } + return 0; +} + ScheduleHazardRecognizer::HazardType SystemZHazardRecognizer:: getHazardType(SUnit *SU, int Stalls) { return (fitsIntoCurrentGroup(SU) ? NoHazard : Hazard); @@ -85,6 +257,7 @@ GrpCount = 0; LastFPdOpCycleIdx = UINT_MAX; LastEmittedMI = nullptr; + B2BWSides.clear(); LLVM_DEBUG(CurGroupDbg = "";); } @@ -165,8 +338,9 @@ #ifndef NDEBUG // Debug output void SystemZHazardRecognizer::dumpSU(SUnit *SU, raw_ostream &OS) const { + const MachineInstr *MI = SU->getInstr(); OS << "SU(" << SU->NodeNum << "):"; - OS << TII->getName(SU->getInstr()->getOpcode()); + OS << TII->getName(MI->getOpcode()); const MCSchedClassDesc *SC = getSchedClass(SU); if (!SC->isValid()) @@ -175,8 +349,10 @@ for (TargetSchedModel::ProcResIter PI = SchedModel->getWriteProcResBegin(SC), PE = SchedModel->getWriteProcResEnd(SC); PI != PE; ++PI) { - const MCProcResourceDesc &PRD = - *SchedModel->getProcResource(PI->ProcResourceIdx); + unsigned PIdx = PI->ProcResourceIdx; + if (!isCountedProcResource(PIdx)) + continue; + const MCProcResourceDesc &PRD = *SchedModel->getProcResource(PIdx); std::string FU(PRD.Name); // trim e.g. Z13_FXaUnit -> FXa FU = FU.substr(FU.find('_') + 1); @@ -201,8 +377,14 @@ OS << "/EndsGroup"; if (SU->isUnbuffered) OS << "/Unbuffered"; - if (has4RegOps(SU->getInstr())) + if (has4RegOps(MI)) OS << "/4RegOps"; + + if (isB2BOpIdx(SU, 0, true/*Def*/)) + OS << "/" << TRI->getName(MI->getOperand(0).getReg()) << ":B2BW"; + for (unsigned Idx = 0; Idx < MI->getNumOperands(); ++Idx) + if (isB2BOpIdx(SU, Idx, false/*Def*/)) + OS << "/" << TRI->getName(MI->getOperand(Idx).getReg()) << ":B2BR"; } void SystemZHazardRecognizer::dumpCurrGroup(std::string Msg) const { @@ -247,8 +429,8 @@ void SystemZHazardRecognizer::dumpState() const { dumpCurrGroup("| Current decoder group"); - dbgs() << "++ | Current cycle index: " - << getCurrCycleIdx() << "\n"; + dbgs() << "++ | Current side: " << (getCurrCycleIdx() < 3 ? "Left" : "Right") + << "\n"; dumpProcResourceCounters(); if (LastFPdOpCycleIdx != UINT_MAX) dbgs() << "++ | Last FPd cycle index: " << LastFPdOpCycleIdx << "\n"; @@ -299,6 +481,8 @@ // Don't handle FPd together with the other resources. if (SchedModel->getProcResource(PI->ProcResourceIdx)->BufferSize == 1) continue; + if (!isCountedProcResource(PI->ProcResourceIdx)) + continue; int &CurrCounter = ProcResourceCounters[PI->ProcResourceIdx]; CurrCounter += PI->Cycles; @@ -323,6 +507,9 @@ << "\n";); } + if (isB2BOpIdx(SU, 0, true/*Def*/)) + B2BWSides[SU] = willGoLeft(SU); + // Insert SU into current group by increasing number of slots used // in current group. CurrGroupSize += getNumDecoderSlots(SU); @@ -407,6 +594,66 @@ return Cost; } +void SystemZHazardRecognizer::B2BReadCost(SUnit *SU, unsigned &NumGood, + unsigned &NumBad, bool FlipSide) const { + int RegsSameSide = 0; + int RegsOppositeSide = 0; + for (SDep &Pred : SU->Preds) { + SUnit *P = Pred.getSUnit(); + if (Pred.getKind() == SDep::Data && isB2BEdge(P, SU, Pred.getReg())) { + if (B2BWSides.count(P)) { + if (wasScheduledLeft(P) == (willGoLeft(SU) ^ FlipSide)) + RegsSameSide++; + else + RegsOppositeSide++; + } + } + } + NumGood = RegsSameSide; + NumBad = RegsOppositeSide; +} + +int SystemZHazardRecognizer::B2BCost(SUnit *SU) { + unsigned CurrIdx = getCurrCycleIdx(SU); + bool OnLastSlot = (CurrIdx == 2 || CurrIdx == 5); + bool OnFirstSlot = (CurrIdx == 0 || CurrIdx == 3); + + // Put B2BR register use on same side as previous def(s). + unsigned NumGood = 0; + unsigned NumBad = 0; + B2BReadCost(SU, NumGood, NumBad); + if (!NumBad && NumGood) + return -4; + if (!NumGood && NumBad) + return 4; + + B2BWriteMetrics M; + B2BWriteCost(SU, M); + int WriteCost = analyzeB2BWrite(M, getCurrCycleIdx(SU) % 3); + if (WriteCost != 0) + return WriteCost; + + // If SU would make a B2B successor available in same group, schedule it. + if (!OnLastSlot) + for (SDep &SuccDep : SU->Succs) { + SUnit *SuccSU = SuccDep.getSUnit(); + if (!SuccSU->isBoundaryNode() && !getSchedClass(SuccSU)->BeginGroup && + isAvailable(SuccSU, SU)) { + B2BReadCost(SuccSU, NumGood, NumBad); + if (!NumBad && NumGood) + return -1; + if (OnFirstSlot) { + B2BWriteMetrics M; + B2BWriteCost(SuccSU, M); + if (M.NumReaders) + return -1; + } + } + } + + return 0; +} + void SystemZHazardRecognizer::emitInstruction(MachineInstr *MI, bool TakenBranch) { // Make a temporary SUnit. Index: llvm/lib/Target/SystemZ/SystemZMachineScheduler.h =================================================================== --- llvm/lib/Target/SystemZ/SystemZMachineScheduler.h +++ llvm/lib/Target/SystemZ/SystemZMachineScheduler.h @@ -31,6 +31,7 @@ const MachineLoopInfo *MLI; const SystemZInstrInfo *TII; + const TargetRegisterInfo *TRI; // A SchedModel is needed before any DAG is built while advancing past // non-scheduled instructions, so it would not always be possible to call @@ -47,6 +48,9 @@ /// The processor resources cost. int ResourcesCost = 0; + /// The (negative) B2B cost of FXU registers. + int B2BCost = 0; + Candidate() = default; Candidate(SUnit *SU_, SystemZHazardRecognizer &HazardRec); @@ -54,8 +58,14 @@ bool operator<(const Candidate &other); // Check if this node is free of cost ("as good as any"). - bool noCost() const { - return (GroupingCost <= 0 && !ResourcesCost); + bool noCost(unsigned &NumTried) const { + if (GroupingCost <= 0 && !ResourcesCost) { + if (B2BCost == -4 || NumTried >= 6) + return true; + else + NumTried++; + } + return false; } #ifndef NDEBUG @@ -64,6 +74,8 @@ dbgs() << " Grouping cost:" << GroupingCost; if (ResourcesCost != 0) dbgs() << " Resource cost:" << ResourcesCost; + if (B2BCost != 0) + dbgs() << " B2BCost:" << B2BCost; } #endif }; Index: llvm/lib/Target/SystemZ/SystemZMachineScheduler.cpp =================================================================== --- llvm/lib/Target/SystemZ/SystemZMachineScheduler.cpp +++ llvm/lib/Target/SystemZ/SystemZMachineScheduler.cpp @@ -16,6 +16,7 @@ #include "SystemZMachineScheduler.h" #include "llvm/CodeGen/MachineLoopInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" using namespace llvm; @@ -73,6 +74,7 @@ void SystemZPostRASchedStrategy::initialize(ScheduleDAGMI *dag) { Available.clear(); // -misched-cutoff. + HazardRec->clearSUMappings(); LLVM_DEBUG(HazardRec->dumpState();); } @@ -82,18 +84,19 @@ LLVM_DEBUG(dbgs() << "** Entering " << printMBBReference(*NextMBB)); MBB = NextMBB; + const MachineLoop *Loop = MLI->getLoopFor(MBB); /// Create a HazardRec for MBB, save it in SchedStates and set HazardRec to /// point to it. - HazardRec = SchedStates[MBB] = new SystemZHazardRecognizer(TII, &SchedModel); - LLVM_DEBUG(const MachineLoop *Loop = MLI->getLoopFor(MBB); - if (Loop && Loop->getHeader() == MBB) dbgs() << " (Loop header)"; - dbgs() << ":\n";); + HazardRec = SchedStates[MBB] = new SystemZHazardRecognizer(TII, TRI, + &SchedModel); + LLVM_DEBUG(if(Loop && Loop->getHeader() == MBB) + dbgs() << " (Loop header)"; + dbgs() << ":\n";); // Try to take over the state from a single predecessor, if it has been // scheduled. If this is not possible, we are done. - MachineBasicBlock *SinglePredMBB = - getSingleSchedPred(MBB, MLI->getLoopFor(MBB)); + MachineBasicBlock *SinglePredMBB = getSingleSchedPred(MBB, Loop); if (SinglePredMBB == nullptr || SchedStates.find(SinglePredMBB) == SchedStates.end()) return; @@ -131,6 +134,7 @@ : MLI(C->MLI), TII(static_cast (C->MF->getSubtarget().getInstrInfo())), + TRI(C->MF->getRegInfo().getTargetRegisterInfo()), MBB(nullptr), HazardRec(nullptr) { const TargetSubtargetInfo *ST = &C->MF->getSubtarget(); SchedModel.init(ST); @@ -174,6 +178,7 @@ LLVM_DEBUG(dbgs() << "** Available: "; Available.dump(*HazardRec);); Candidate Best; + unsigned NumTried = 0; for (auto *SU : Available) { // SU is the next candidate to be compared against current Best. @@ -190,7 +195,7 @@ // Once we know we have seen all SUs that affect grouping or use unbuffered // resources, we can stop iterating if Best looks good. - if (!SU->isScheduleHigh && Best.noCost()) + if (!SU->isScheduleHigh && Best.noCost(NumTried)) break; } @@ -198,6 +203,10 @@ return Best.SU; } +// EXPERIMENTAL +#include "llvm/Support/CommandLine.h" +static cl::opt SIDESTEERING_FXU("sidesteer-fxu", cl::init(false)); + SystemZPostRASchedStrategy::Candidate:: Candidate(SUnit *SU_, SystemZHazardRecognizer &HazardRec) : Candidate() { SU = SU_; @@ -209,8 +218,16 @@ // Check the resources cost for this SU. ResourcesCost = HazardRec.resourcesCost(SU); + + // Side steering + if (SIDESTEERING_FXU) + B2BCost = HazardRec.B2BCost(SU); } +// EXPERIMENTAL +#include "llvm/Support/CommandLine.h" +static cl::opt B2B_HCUT("b2b-hcut", cl::init(INT_MIN)); + bool SystemZPostRASchedStrategy::Candidate:: operator<(const Candidate &other) { @@ -226,6 +243,13 @@ if (ResourcesCost > other.ResourcesCost) return false; + // Try to help FXU bypassing. + int HDiff = (((int) SU->getHeight()) - ((int) other.SU->getHeight())); + if (B2BCost < other.B2BCost && HDiff >= B2B_HCUT) + return true; + if (B2BCost > other.B2BCost && HDiff <= -(B2B_HCUT)) // XXX needed? + return false; + // Higher SU is otherwise generally better. if (SU->getHeight() > other.SU->getHeight()) return true; @@ -242,7 +266,8 @@ void SystemZPostRASchedStrategy::schedNode(SUnit *SU, bool IsTopNode) { LLVM_DEBUG(dbgs() << "** Scheduling SU(" << SU->NodeNum << ") "; if (Available.size() == 1) dbgs() << "(only one) "; - Candidate c(SU, *HazardRec); c.dumpCosts(); dbgs() << "\n";); + // Candidate c(SU, *HazardRec); c.dumpCosts(); + dbgs() << "\n";); // Remove SU from Available set and update HazardRec. Available.erase(SU); Index: llvm/lib/Target/SystemZ/SystemZSchedule.td =================================================================== --- llvm/lib/Target/SystemZ/SystemZSchedule.td +++ llvm/lib/Target/SystemZ/SystemZSchedule.td @@ -59,6 +59,10 @@ def MCD : SchedWrite; // Millicode +def B2BRW : SchedWrite; // Reads and Writes the back-to-back vector. +def B2BRn : SchedWrite; // Reads the back-to-back vector. +def B2BnW : SchedWrite; // Writes the back-to-back vector. + include "SystemZScheduleZ15.td" include "SystemZScheduleZ14.td" include "SystemZScheduleZ13.td" Index: llvm/lib/Target/SystemZ/SystemZScheduleZ14.td =================================================================== --- llvm/lib/Target/SystemZ/SystemZScheduleZ14.td +++ llvm/lib/Target/SystemZ/SystemZScheduleZ14.td @@ -80,6 +80,9 @@ def Z14_VecFPdUnit : ProcResource<2> { let BufferSize = 1; /* blocking */ } def Z14_VBUnit : ProcResource<2>; def Z14_MCD : ProcResource<1>; +def Z14_B2BRW : ProcResource<6>; // Avoid becoming the critical resource +def Z14_B2BRn : ProcResource<6>; +def Z14_B2BnW : ProcResource<6>; // Subtarget specific definitions of scheduling resources. let NumMicroOps = 0 in { @@ -113,6 +116,12 @@ let BeginGroup = 1; let EndGroup = 1; } +let NumMicroOps = 0 in { + def : WriteRes {} + def : WriteRes {} + def : WriteRes {} +} + // -------------------------- INSTRUCTIONS ---------------------------------- // // InstRW constructs have been used in order to preserve the @@ -126,7 +135,7 @@ //===----------------------------------------------------------------------===// // Pseudo -> LA / LAY -def : InstRW<[WLat1, FXa, NormalGr], (instregex "ADJDYNALLOC$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "ADJDYNALLOC$")>; //===----------------------------------------------------------------------===// // Branch instructions @@ -138,7 +147,7 @@ def : InstRW<[WLat1, FXb, NormalGr], (instregex "(Call)?BC(R)?(Asm.*)?$")>; def : InstRW<[WLat1, FXb, NormalGr], (instregex "(Call)?B(R)?(Asm.*)?$")>; def : InstRW<[WLat1, FXb, LSU, NormalGr], (instregex "BI(C)?(Asm.*)?$")>; -def : InstRW<[WLat1, FXa, EndGroup], (instregex "BRCT(G)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, EndGroup], (instregex "BRCT(G)?$")>; def : InstRW<[WLat1, FXa, FXb, GroupAlone], (instregex "BRCTH$")>; def : InstRW<[WLat1, FXa, FXb, GroupAlone], (instregex "BCT(G)?(R)?$")>; def : InstRW<[WLat1, FXa2, FXb2, GroupAlone2], @@ -167,10 +176,12 @@ //===----------------------------------------------------------------------===// // Call -def : InstRW<[WLat1, VBU, FXa2, GroupAlone], (instregex "(Call)?BRAS$")>; -def : InstRW<[WLat1, FXa2, FXb, GroupAlone], (instregex "(Call)?BRASL$")>; -def : InstRW<[WLat1, FXa2, FXb, GroupAlone], (instregex "(Call)?BAS(R)?$")>; -def : InstRW<[WLat1, FXa2, FXb, GroupAlone], (instregex "TLS_(G|L)DCALL$")>; +def : InstRW<[WLat1, VBU, FXa2, B2BRW, GroupAlone], (instregex "(Call)?BRAS$")>; +def : InstRW<[WLat1, FXa2, FXb, B2BRW, GroupAlone], (instregex "(Call)?BRASL$")>; +def : InstRW<[WLat1, FXa2, FXb, B2BRW, GroupAlone], + (instregex "(Call)?BAS(R)?$")>; +def : InstRW<[WLat1, FXa2, FXb, B2BRW, GroupAlone], + (instregex "TLS_(G|L)DCALL$")>; // Return def : InstRW<[WLat1, FXb, EndGroup], (instregex "Return$")>; @@ -189,10 +200,10 @@ def : InstRW<[WLat30, WLat30, WLat30, MCD], (instregex "MVCL(E|U)?$")>; // Pseudo -> reg move -def : InstRW<[WLat1, FXa, NormalGr], (instregex "COPY(_TO_REGCLASS)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "EXTRACT_SUBREG$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "INSERT_SUBREG$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "REG_SEQUENCE$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "COPY(_TO_REGCLASS)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "EXTRACT_SUBREG$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "INSERT_SUBREG$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "REG_SEQUENCE$")>; // Loads def : InstRW<[LSULatency, LSU, NormalGr], (instregex "L(Y|FH|RL|Mux)?$")>; @@ -200,12 +211,13 @@ def : InstRW<[LSULatency, LSU, NormalGr], (instregex "LG(RL)?$")>; def : InstRW<[LSULatency, LSU, NormalGr], (instregex "L128$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LLIH(F|H|L)$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LLIL(F|H|L)$")>; +def : InstRW<[WLat1, FXa, B2BnW, NormalGr], (instregex "LLI(H|L)F$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LLI(H|L)(H|L)$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LG(F|H)I$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LHI(Mux)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LR$")>; +def : InstRW<[WLat1, FXa, B2BnW, NormalGr], (instregex "LGFI$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LGHI$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LHI(Mux)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LR$")>; // Load and zero rightmost byte def : InstRW<[LSULatency, LSU, NormalGr], (instregex "LZR(F|G)$")>; @@ -214,8 +226,9 @@ def : InstRW<[WLat1LSU, FXb, LSU, NormalGr], (instregex "L(FH|G)?AT$")>; // Load and test -def : InstRW<[WLat1LSU, WLat1LSU, LSU, FXa, NormalGr], (instregex "LT(G)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LT(G)?R$")>; +def : InstRW<[WLat1LSU, WLat1LSU, LSU, FXa, B2BRW, NormalGr], + (instregex "LT(G)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LT(G)?R$")>; // Stores def : InstRW<[WLat1, FXb, LSU, NormalGr], (instregex "STG(RL)?$")>; @@ -229,10 +242,11 @@ // Conditional move instructions //===----------------------------------------------------------------------===// -def : InstRW<[WLat2, FXa, NormalGr], (instregex "LOCRMux$")>; -def : InstRW<[WLat2, FXa, NormalGr], (instregex "LOC(G|FH)?R(Asm.*)?$")>; -def : InstRW<[WLat2, FXa, NormalGr], (instregex "LOC(G|H)?HI(Mux|(Asm.*))?$")>; -def : InstRW<[WLat2LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat2, FXa, B2BnW, NormalGr], (instregex "LOCRMux$")>; +def : InstRW<[WLat2, FXa, B2BnW, NormalGr], (instregex "LOC(G|FH)?R(Asm.*)?$")>; +def : InstRW<[WLat2, FXa, B2BnW, NormalGr], + (instregex "LOC(G|H)?HI(Mux|(Asm.*))?$")>; +def : InstRW<[WLat2LSU, RegReadAdv, FXa, LSU, B2BnW, NormalGr], (instregex "LOC(G|FH|Mux)?(Asm.*)?$")>; def : InstRW<[WLat1, FXb, LSU, NormalGr], (instregex "STOC(G|FH|Mux)?(Asm.*)?$")>; @@ -241,28 +255,30 @@ // Sign extensions //===----------------------------------------------------------------------===// -def : InstRW<[WLat1, FXa, NormalGr], (instregex "L(B|H|G)R$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LG(B|H|F)R$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "L(B|H|G)R$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LG(B|H|F)R$")>; -def : InstRW<[WLat1LSU, WLat1LSU, FXa, LSU, NormalGr], (instregex "LTGF$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LTGFR$")>; +def : InstRW<[WLat1LSU, WLat1LSU, FXa, LSU, B2BnW, NormalGr], + (instregex "LTGF$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LTGFR$")>; -def : InstRW<[WLat1LSU, FXa, LSU, NormalGr], (instregex "LB(H|Mux)?$")>; -def : InstRW<[WLat1LSU, FXa, LSU, NormalGr], (instregex "LH(Y)?$")>; -def : InstRW<[WLat1LSU, FXa, LSU, NormalGr], (instregex "LH(H|Mux|RL)$")>; -def : InstRW<[WLat1LSU, FXa, LSU, NormalGr], (instregex "LG(B|H|F)$")>; -def : InstRW<[WLat1LSU, FXa, LSU, NormalGr], (instregex "LG(H|F)RL$")>; +def : InstRW<[WLat1LSU, FXa, LSU, B2BnW, NormalGr], (instregex "LB(H|Mux)?$")>; +def : InstRW<[WLat1LSU, FXa, LSU, B2BnW, NormalGr], (instregex "LH(Y)?$")>; +def : InstRW<[WLat1LSU, FXa, LSU, B2BnW, NormalGr], (instregex "LH(H|Mux|RL)$")>; +def : InstRW<[WLat1LSU, FXa, LSU, B2BnW, NormalGr], (instregex "LGB$")>; +def : InstRW<[WLat1LSU, FXa, LSU, B2BRW, NormalGr], (instregex "LG(H|F)$")>; +def : InstRW<[WLat1LSU, FXa, LSU, B2BnW, NormalGr], (instregex "LG(H|F)RL$")>; //===----------------------------------------------------------------------===// // Zero extensions //===----------------------------------------------------------------------===// -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LLCR(Mux)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LLHR(Mux)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LLG(C|H|F|T)R$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LLCR(Mux)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LLHR(Mux)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LLG(C|H|F|T)R$")>; def : InstRW<[LSULatency, LSU, NormalGr], (instregex "LLC(Mux)?$")>; def : InstRW<[LSULatency, LSU, NormalGr], (instregex "LLH(Mux)?$")>; -def : InstRW<[WLat1LSU, FXa, LSU, NormalGr], (instregex "LL(C|H)H$")>; +def : InstRW<[WLat1LSU, FXa, LSU, B2BnW, NormalGr], (instregex "LL(C|H)H$")>; def : InstRW<[LSULatency, LSU, NormalGr], (instregex "LLHRL$")>; def : InstRW<[LSULatency, LSU, NormalGr], (instregex "LLG(C|H|F|T|HRL|FRL)$")>; @@ -297,8 +313,8 @@ // Byte swaps //===----------------------------------------------------------------------===// -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LRV(G)?R$")>; -def : InstRW<[WLat1LSU, FXa, LSU, NormalGr], (instregex "LRV(G|H)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LRV(G)?R$")>; +def : InstRW<[WLat1LSU, FXa, LSU, B2BRW, NormalGr], (instregex "LRV(G|H)?$")>; def : InstRW<[WLat1, FXb, LSU, NormalGr], (instregex "STRV(G|H)?$")>; def : InstRW<[WLat30, MCD], (instregex "MVCIN$")>; @@ -306,223 +322,231 @@ // Load address instructions //===----------------------------------------------------------------------===// -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LA(Y|RL)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LA(Y)?$")>; +def : InstRW<[WLat1, FXa, B2BnW, NormalGr], (instregex "LARL?$")>; // Load the Global Offset Table address ( -> larl ) -def : InstRW<[WLat1, FXa, NormalGr], (instregex "GOT$")>; +def : InstRW<[WLat1, FXa, B2BnW, NormalGr], (instregex "GOT$")>; //===----------------------------------------------------------------------===// // Absolute and Negation //===----------------------------------------------------------------------===// -def : InstRW<[WLat1, WLat1, FXa, NormalGr], (instregex "LP(G)?R$")>; -def : InstRW<[WLat2, WLat2, FXa2, Cracked], (instregex "L(N|P)GFR$")>; -def : InstRW<[WLat1, WLat1, FXa, NormalGr], (instregex "LN(R|GR)$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LC(R|GR)$")>; -def : InstRW<[WLat2, WLat2, FXa2, Cracked], (instregex "LCGFR$")>; +def : InstRW<[WLat1, WLat1, FXa, B2BRW, NormalGr], (instregex "LP(G)?R$")>; +def : InstRW<[WLat2, WLat2, FXa2, B2BRW, Cracked], (instregex "L(N|P)GFR$")>; +def : InstRW<[WLat1, WLat1, FXa, B2BRW, NormalGr], (instregex "LN(R|GR)$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LC(R|GR)$")>; +def : InstRW<[WLat2, WLat2, FXa2, B2BRW, Cracked], (instregex "LCGFR$")>; //===----------------------------------------------------------------------===// // Insertion //===----------------------------------------------------------------------===// -def : InstRW<[WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], (instregex "IC(Y)?$")>; -def : InstRW<[WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], + (instregex "IC(Y)?$")>; +def : InstRW<[WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "IC32(Y)?$")>; -def : InstRW<[WLat1LSU, RegReadAdv, WLat1LSU, FXa, LSU, NormalGr], +def : InstRW<[WLat1LSU, RegReadAdv, WLat1LSU, FXa, LSU, B2BRW, NormalGr], (instregex "ICM(H|Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "II(F|H|L)Mux$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "IIHF(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "IIHH(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "IIHL(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "IILF(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "IILH(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "IILL(64)?$")>; +def : InstRW<[WLat1, FXa, B2BnW, NormalGr], (instregex "IIFMux$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "II(H|L)Mux$")>; +def : InstRW<[WLat1, FXa, B2BnW, NormalGr], (instregex "IIHF(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "IIHH(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "IIHL(64)?$")>; +def : InstRW<[WLat1, FXa, B2BnW, NormalGr], (instregex "IILF(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "IILH(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "IILL(64)?$")>; //===----------------------------------------------------------------------===// // Addition //===----------------------------------------------------------------------===// -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "A(Y)?$")>; -def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "AH(Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AIH$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AFI(Mux)?$")>; -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AIH$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AFI(Mux)?$")>; +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "AG$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AGFI$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AGHI(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AGR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AHI(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AHIMux(K)?$")>; -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AGFI$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AGHI(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AGR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AHI(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AHIMux(K)?$")>; +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "AL(Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AL(FI|HSIK)$")>; -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AL(FI|HSIK)$")>; +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "ALG(F)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "ALGHSIK$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "ALGF(I|R)$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "ALGR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "ALR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "A(L)?HHHR$")>; -def : InstRW<[WLat2, WLat2, FXa, NormalGr], (instregex "A(L)?HHLR$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "ALSIH(N)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "ALGHSIK$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "ALGF(I|R)$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "ALGR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "ALR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "A(L)?HHHR$")>; +def : InstRW<[WLat2, WLat2, FXa, B2BRW, NormalGr], (instregex "A(L)?HHLR$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "ALSIH(N)?$")>; def : InstRW<[WLat2LSU, FXb, LSU, NormalGr], (instregex "A(L)?(G)?SI$")>; // Logical addition with carry -def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, GroupAlone], +def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, B2BnW, GroupAlone], (instregex "ALC(G)?$")>; -def : InstRW<[WLat2, WLat2, FXa, GroupAlone], (instregex "ALC(G)?R$")>; +def : InstRW<[WLat2, WLat2, FXa, B2BnW, GroupAlone], (instregex "ALC(G)?R$")>; // Add with sign extension (16/32 -> 64) -def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "AG(F|H)$")>; -def : InstRW<[WLat2, WLat2, FXa, NormalGr], (instregex "AGFR$")>; +def : InstRW<[WLat2, WLat2, FXa, B2BRW, NormalGr], (instregex "AGFR$")>; //===----------------------------------------------------------------------===// // Subtraction //===----------------------------------------------------------------------===// -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "S(G|Y)?$")>; -def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "SH(Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SGR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SLFI$")>; -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SGR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SLFI$")>; +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "SL(G|GF|Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SLGF(I|R)$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SLGR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SLR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "S(L)?HHHR$")>; -def : InstRW<[WLat2, WLat2, FXa, NormalGr], (instregex "S(L)?HHLR$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SLGF(I|R)$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SLGR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SLR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "S(L)?HHHR$")>; +def : InstRW<[WLat2, WLat2, FXa, B2BRW, NormalGr], (instregex "S(L)?HHLR$")>; // Subtraction with borrow -def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, GroupAlone], +def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, B2BnW, GroupAlone], (instregex "SLB(G)?$")>; -def : InstRW<[WLat2, WLat2, FXa, GroupAlone], (instregex "SLB(G)?R$")>; +def : InstRW<[WLat2, WLat2, FXa, B2BnW, GroupAlone], (instregex "SLB(G)?R$")>; // Subtraction with sign extension (16/32 -> 64) -def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "SG(F|H)$")>; -def : InstRW<[WLat2, WLat2, FXa, NormalGr], (instregex "SGFR$")>; +def : InstRW<[WLat2, WLat2, FXa, B2BRW, NormalGr], (instregex "SGFR$")>; //===----------------------------------------------------------------------===// // AND //===----------------------------------------------------------------------===// -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "N(G|Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NGR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NI(FMux|HMux|LMux)$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NGR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NI(FMux|HMux|LMux)$")>; def : InstRW<[WLat2LSU, FXb, LSU, NormalGr], (instregex "NI(Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NIHF(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NIHH(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NIHL(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NILF(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NILH(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NILL(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NIHF(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NIHH(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NIHL(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NILF(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NILH(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NILL(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NR(K)?$")>; def : InstRW<[WLat3LSU, LSU2, FXb, Cracked], (instregex "NC$")>; //===----------------------------------------------------------------------===// // OR //===----------------------------------------------------------------------===// -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "O(G|Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OGR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OGR(K)?$")>; def : InstRW<[WLat2LSU, FXb, LSU, NormalGr], (instregex "OI(Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OI(FMux|HMux|LMux)$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OIHF(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OIHH(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OIHL(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OILF(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OILH(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OILL(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OI(FMux|HMux|LMux)$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OIHF(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OIHH(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OIHL(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OILF(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OILH(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OILL(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OR(K)?$")>; def : InstRW<[WLat3LSU, LSU2, FXb, Cracked], (instregex "OC$")>; //===----------------------------------------------------------------------===// // XOR //===----------------------------------------------------------------------===// -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "X(G|Y)?$")>; def : InstRW<[WLat2LSU, FXb, LSU, NormalGr], (instregex "XI(Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "XIFMux$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "XGR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "XIHF(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "XILF(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "XR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "XIFMux$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "XGR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "XIHF(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "XILF(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "XR(K)?$")>; def : InstRW<[WLat3LSU, LSU2, FXb, Cracked], (instregex "XC$")>; //===----------------------------------------------------------------------===// // Multiplication //===----------------------------------------------------------------------===// -def : InstRW<[WLat5LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat5LSU, RegReadAdv, FXa, LSU, B2BRn, NormalGr], (instregex "MS(GF|Y)?$")>; -def : InstRW<[WLat5, FXa, NormalGr], (instregex "MS(R|FI)$")>; -def : InstRW<[WLat7LSU, RegReadAdv, FXa, LSU, NormalGr], (instregex "MSG$")>; -def : InstRW<[WLat7, FXa, NormalGr], (instregex "MSGR$")>; -def : InstRW<[WLat5, FXa, NormalGr], (instregex "MSGF(I|R)$")>; -def : InstRW<[WLat8LSU, RegReadAdv, FXa2, LSU, GroupAlone], (instregex "MLG$")>; -def : InstRW<[WLat8, FXa2, GroupAlone], (instregex "MLGR$")>; -def : InstRW<[WLat4, FXa, NormalGr], (instregex "MGHI$")>; -def : InstRW<[WLat4, FXa, NormalGr], (instregex "MHI$")>; -def : InstRW<[WLat4LSU, RegReadAdv, FXa, LSU, NormalGr], (instregex "MH(Y)?$")>; -def : InstRW<[WLat6, FXa2, GroupAlone], (instregex "M(L)?R$")>; -def : InstRW<[WLat6LSU, RegReadAdv, FXa2, LSU, GroupAlone], +def : InstRW<[WLat5, FXa, B2BRn, NormalGr], (instregex "MS(R|FI)$")>; +def : InstRW<[WLat7LSU, RegReadAdv, FXa, LSU, B2BRn, NormalGr], + (instregex "MSG$")>; +def : InstRW<[WLat7, FXa, B2BRn, NormalGr], (instregex "MSGR$")>; +def : InstRW<[WLat5, FXa, B2BRn, NormalGr], (instregex "MSGF(I|R)$")>; +def : InstRW<[WLat8LSU, RegReadAdv, FXa2, LSU, B2BRn, GroupAlone], + (instregex "MLG$")>; +def : InstRW<[WLat8, FXa2, B2BRn, GroupAlone], (instregex "MLGR$")>; +def : InstRW<[WLat4, FXa, B2BRW, NormalGr], (instregex "MGHI$")>; +def : InstRW<[WLat4, FXa, B2BRW, NormalGr], (instregex "MHI$")>; +def : InstRW<[WLat4LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], + (instregex "MH(Y)?$")>; +def : InstRW<[WLat6, FXa2, B2BRn, GroupAlone], (instregex "M(L)?R$")>; +def : InstRW<[WLat6LSU, RegReadAdv, FXa2, LSU, B2BRn, GroupAlone], (instregex "M(FY|L)?$")>; -def : InstRW<[WLat8, RegReadAdv, FXa, LSU, NormalGr], (instregex "MGH$")>; -def : InstRW<[WLat12, RegReadAdv, FXa2, LSU, GroupAlone], (instregex "MG$")>; -def : InstRW<[WLat8, FXa2, GroupAlone], (instregex "MGRK$")>; -def : InstRW<[WLat6LSU, WLat6LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat8, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "MGH$")>; +def : InstRW<[WLat12, RegReadAdv, FXa2, LSU, B2BRn, GroupAlone], + (instregex "MG$")>; +def : InstRW<[WLat8, FXa2, B2BRn, GroupAlone], (instregex "MGRK$")>; +def : InstRW<[WLat6LSU, WLat6LSU, RegReadAdv, FXa, LSU, B2BRn, NormalGr], (instregex "MSC$")>; -def : InstRW<[WLat8LSU, WLat8LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat8LSU, WLat8LSU, RegReadAdv, FXa, LSU, B2BRn, NormalGr], (instregex "MSGC$")>; -def : InstRW<[WLat6, WLat6, FXa, NormalGr], (instregex "MSRKC$")>; -def : InstRW<[WLat8, WLat8, FXa, NormalGr], (instregex "MSGRKC$")>; +def : InstRW<[WLat6, WLat6, FXa, B2BRn, NormalGr], (instregex "MSRKC$")>; +def : InstRW<[WLat8, WLat8, FXa, B2BRn, NormalGr], (instregex "MSGRKC$")>; //===----------------------------------------------------------------------===// // Division and remainder //===----------------------------------------------------------------------===// -def : InstRW<[WLat20, FXa4, GroupAlone], (instregex "DR$")>; -def : InstRW<[WLat30, RegReadAdv, FXa4, LSU, GroupAlone2], (instregex "D$")>; -def : InstRW<[WLat30, FXa2, GroupAlone], (instregex "DSG(F)?R$")>; -def : InstRW<[WLat30, RegReadAdv, FXa2, LSU, GroupAlone2], +def : InstRW<[WLat20, FXa4, B2BRn, GroupAlone], (instregex "DR$")>; +def : InstRW<[WLat30, RegReadAdv, FXa4, LSU, B2BRn, GroupAlone2], + (instregex "D$")>; +def : InstRW<[WLat30, FXa2, B2BRn, GroupAlone], (instregex "DSG(F)?R$")>; +def : InstRW<[WLat30, RegReadAdv, FXa2, LSU, B2BRn, GroupAlone2], (instregex "DSG(F)?$")>; -def : InstRW<[WLat20, FXa4, GroupAlone], (instregex "DLR$")>; -def : InstRW<[WLat30, FXa4, GroupAlone], (instregex "DLGR$")>; -def : InstRW<[WLat30, RegReadAdv, FXa4, LSU, GroupAlone2], +def : InstRW<[WLat20, FXa4, B2BRn, GroupAlone], (instregex "DLR$")>; +def : InstRW<[WLat30, FXa4, B2BRn, GroupAlone], (instregex "DLGR$")>; +def : InstRW<[WLat30, RegReadAdv, FXa4, LSU, B2BRn, GroupAlone2], (instregex "DL(G)?$")>; //===----------------------------------------------------------------------===// // Shifts //===----------------------------------------------------------------------===// -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SLL(G|K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SRL(G|K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SRA(G|K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SLA(G|K)?$")>; -def : InstRW<[WLat5LSU, WLat5LSU, FXa4, LSU, GroupAlone2], +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SLL(G|K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SRL(G|K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SRA(G|K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SLA(G|K)?$")>; +def : InstRW<[WLat5LSU, WLat5LSU, FXa4, LSU, B2BRW, GroupAlone2], (instregex "S(L|R)D(A|L)$")>; // Rotate -def : InstRW<[WLat2LSU, FXa, LSU, NormalGr], (instregex "RLL(G)?$")>; +def : InstRW<[WLat2LSU, FXa, LSU, B2BRW, NormalGr], (instregex "RLL(G)?$")>; // Rotate and insert -def : InstRW<[WLat1, FXa, NormalGr], (instregex "RISBG(N|32)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "RISBH(G|H|L)$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "RISBL(G|H|L)$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "RISBMux$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "RISBG(N|32)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "RISBH(G|H|L)$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "RISBL(G|H|L)$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "RISBMux$")>; // Rotate and Select -def : InstRW<[WLat2, WLat2, FXa2, Cracked], (instregex "R(N|O|X)SBG$")>; +def : InstRW<[WLat2, WLat2, FXa2, B2BRW, Cracked], (instregex "R(N|O|X)SBG$")>; //===----------------------------------------------------------------------===// // Comparison @@ -616,7 +640,7 @@ (instregex "CS(G|Y)?$")>; // Compare double and swap -def : InstRW<[WLat6LSU, WLat6LSU, FXa3, FXb2, LSU, GroupAlone2], +def : InstRW<[WLat6LSU, WLat6LSU, FXa3, FXb2, LSU, B2BnW, GroupAlone2], (instregex "CDS(Y)?$")>; def : InstRW<[WLat15, WLat15, FXa2, FXb4, LSU3, GroupAlone3], (instregex "CDSG$")>; @@ -710,13 +734,13 @@ //===----------------------------------------------------------------------===// // Insert Program Mask -def : InstRW<[WLat3, FXa, EndGroup], (instregex "IPM$")>; +def : InstRW<[WLat3, FXa, B2BnW, EndGroup], (instregex "IPM$")>; // Set Program Mask def : InstRW<[WLat3, LSU, EndGroup], (instregex "SPM$")>; // Branch and link -def : InstRW<[WLat1, FXa2, FXb, GroupAlone], (instregex "BAL(R)?$")>; +def : InstRW<[WLat1, FXa2, FXb, B2BnW, GroupAlone], (instregex "BAL(R)?$")>; // Test addressing mode def : InstRW<[WLat1, FXb, NormalGr], (instregex "TAM$")>; @@ -725,8 +749,8 @@ def : InstRW<[WLat1, FXb, EndGroup], (instregex "SAM(24|31|64)$")>; // Branch (and save) and set mode. -def : InstRW<[WLat1, FXa, FXb, GroupAlone], (instregex "BSM$")>; -def : InstRW<[WLat1, FXa2, FXb, GroupAlone], (instregex "BASSM$")>; +def : InstRW<[WLat1, FXa, FXb, B2BRW, GroupAlone], (instregex "BSM$")>; +def : InstRW<[WLat1, FXa2, FXb, B2BRW, GroupAlone], (instregex "BASSM$")>; //===----------------------------------------------------------------------===// // Transactional execution @@ -758,10 +782,10 @@ //===----------------------------------------------------------------------===// // Find leftmost one -def : InstRW<[WLat5, WLat5, FXa2, GroupAlone], (instregex "FLOGR$")>; +def : InstRW<[WLat5, WLat5, FXa2, B2BRn, GroupAlone], (instregex "FLOGR$")>; // Population count -def : InstRW<[WLat3, WLat3, FXa, NormalGr], (instregex "POPCNT$")>; +def : InstRW<[WLat3, WLat3, FXa, B2BRW, NormalGr], (instregex "POPCNT$")>; // String instructions def : InstRW<[WLat30, WLat30, WLat30, MCD], (instregex "SRST(U)?$")>; @@ -1501,11 +1525,11 @@ def : InstRW<[WLat30, WLat30, MCD], (instregex "EPSW$")>; def : InstRW<[WLat20, GroupAlone3], (instregex "LPSW(E)?$")>; -def : InstRW<[WLat3, FXa, GroupAlone], (instregex "IPK$")>; +def : InstRW<[WLat3, FXa, B2BRW, GroupAlone], (instregex "IPK$")>; def : InstRW<[WLat1, LSU, EndGroup], (instregex "SPKA$")>; def : InstRW<[WLat1, LSU, EndGroup], (instregex "SSM$")>; def : InstRW<[WLat1, FXb, LSU, GroupAlone], (instregex "ST(N|O)SM$")>; -def : InstRW<[WLat3, FXa, NormalGr], (instregex "IAC$")>; +def : InstRW<[WLat3, FXa, B2BRW, NormalGr], (instregex "IAC$")>; def : InstRW<[WLat1, LSU, EndGroup], (instregex "SAC(F)?$")>; //===----------------------------------------------------------------------===// Index: llvm/lib/Target/SystemZ/SystemZScheduleZ15.td =================================================================== --- llvm/lib/Target/SystemZ/SystemZScheduleZ15.td +++ llvm/lib/Target/SystemZ/SystemZScheduleZ15.td @@ -80,6 +80,9 @@ def Z15_VecFPdUnit : ProcResource<2> { let BufferSize = 1; /* blocking */ } def Z15_VBUnit : ProcResource<2>; def Z15_MCD : ProcResource<1>; +def Z15_B2BRW : ProcResource<6>; // Avoid becoming the critical resource +def Z15_B2BRn : ProcResource<6>; +def Z15_B2BnW : ProcResource<6>; // Subtarget specific definitions of scheduling resources. let NumMicroOps = 0 in { @@ -113,6 +116,12 @@ let BeginGroup = 1; let EndGroup = 1; } +let NumMicroOps = 0 in { + def : WriteRes {} + def : WriteRes {} + def : WriteRes {} +} + // -------------------------- INSTRUCTIONS ---------------------------------- // // InstRW constructs have been used in order to preserve the @@ -126,7 +135,7 @@ //===----------------------------------------------------------------------===// // Pseudo -> LA / LAY -def : InstRW<[WLat1, FXa, NormalGr], (instregex "ADJDYNALLOC$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "ADJDYNALLOC$")>; //===----------------------------------------------------------------------===// // Branch instructions @@ -138,7 +147,7 @@ def : InstRW<[WLat1, FXb, NormalGr], (instregex "(Call)?BC(R)?(Asm.*)?$")>; def : InstRW<[WLat1, FXb, NormalGr], (instregex "(Call)?B(R)?(Asm.*)?$")>; def : InstRW<[WLat1, FXb, LSU, NormalGr], (instregex "BI(C)?(Asm.*)?$")>; -def : InstRW<[WLat1, FXa, EndGroup], (instregex "BRCT(G)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, EndGroup], (instregex "BRCT(G)?$")>; def : InstRW<[WLat1, FXa, FXb, GroupAlone], (instregex "BRCTH$")>; def : InstRW<[WLat1, FXa, FXb, GroupAlone], (instregex "BCT(G)?(R)?$")>; def : InstRW<[WLat1, FXa2, FXb2, GroupAlone2], @@ -167,10 +176,12 @@ //===----------------------------------------------------------------------===// // Call -def : InstRW<[WLat1, VBU, FXa2, GroupAlone], (instregex "(Call)?BRAS$")>; -def : InstRW<[WLat1, FXa2, FXb, GroupAlone], (instregex "(Call)?BRASL$")>; -def : InstRW<[WLat1, FXa2, FXb, GroupAlone], (instregex "(Call)?BAS(R)?$")>; -def : InstRW<[WLat1, FXa2, FXb, GroupAlone], (instregex "TLS_(G|L)DCALL$")>; +def : InstRW<[WLat1, VBU, FXa2, B2BRW, GroupAlone], (instregex "(Call)?BRAS$")>; +def : InstRW<[WLat1, FXa2, FXb, B2BRW, GroupAlone], (instregex "(Call)?BRASL$")>; +def : InstRW<[WLat1, FXa2, FXb, B2BRW, GroupAlone], + (instregex "(Call)?BAS(R)?$")>; +def : InstRW<[WLat1, FXa2, FXb, B2BRW, GroupAlone], + (instregex "TLS_(G|L)DCALL$")>; // Return def : InstRW<[WLat1, FXb, EndGroup], (instregex "Return$")>; @@ -190,10 +201,10 @@ def : InstRW<[WLat1, LSU2, GroupAlone], (instregex "MVCRL$")>; // Pseudo -> reg move -def : InstRW<[WLat1, FXa, NormalGr], (instregex "COPY(_TO_REGCLASS)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "EXTRACT_SUBREG$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "INSERT_SUBREG$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "REG_SEQUENCE$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "COPY(_TO_REGCLASS)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "EXTRACT_SUBREG$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "INSERT_SUBREG$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "REG_SEQUENCE$")>; // Loads def : InstRW<[LSULatency, LSU, NormalGr], (instregex "L(Y|FH|RL|Mux)?$")>; @@ -201,12 +212,13 @@ def : InstRW<[LSULatency, LSU, NormalGr], (instregex "LG(RL)?$")>; def : InstRW<[LSULatency, LSU, NormalGr], (instregex "L128$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LLIH(F|H|L)$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LLIL(F|H|L)$")>; +def : InstRW<[WLat1, FXa, B2BnW, NormalGr], (instregex "LLI(H|L)F$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LLI(H|L)(H|L)$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LG(F|H)I$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LHI(Mux)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LR$")>; +def : InstRW<[WLat1, FXa, B2BnW, NormalGr], (instregex "LGFI$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LGHI$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LHI(Mux)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LR$")>; // Load and zero rightmost byte def : InstRW<[LSULatency, LSU, NormalGr], (instregex "LZR(F|G)$")>; @@ -215,8 +227,9 @@ def : InstRW<[WLat1LSU, FXb, LSU, NormalGr], (instregex "L(FH|G)?AT$")>; // Load and test -def : InstRW<[WLat1LSU, WLat1LSU, LSU, FXa, NormalGr], (instregex "LT(G)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LT(G)?R$")>; +def : InstRW<[WLat1LSU, WLat1LSU, LSU, FXa, B2BRW, NormalGr], + (instregex "LT(G)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LT(G)?R$")>; // Stores def : InstRW<[WLat1, FXb, LSU, NormalGr], (instregex "STG(RL)?$")>; @@ -230,43 +243,46 @@ // Conditional move instructions //===----------------------------------------------------------------------===// -def : InstRW<[WLat2, FXa, NormalGr], (instregex "LOCRMux$")>; -def : InstRW<[WLat2, FXa, NormalGr], (instregex "LOC(G|FH)?R(Asm.*)?$")>; -def : InstRW<[WLat2, FXa, NormalGr], (instregex "LOC(G|H)?HI(Mux|(Asm.*))?$")>; -def : InstRW<[WLat2LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat2, FXa, B2BnW, NormalGr], (instregex "LOCRMux$")>; +def : InstRW<[WLat2, FXa, B2BnW, NormalGr], (instregex "LOC(G|FH)?R(Asm.*)?$")>; +def : InstRW<[WLat2, FXa, B2BnW, NormalGr], + (instregex "LOC(G|H)?HI(Mux|(Asm.*))?$")>; +def : InstRW<[WLat2LSU, RegReadAdv, FXa, LSU, B2BnW, NormalGr], (instregex "LOC(G|FH|Mux)?(Asm.*)?$")>; def : InstRW<[WLat1, FXb, LSU, NormalGr], (instregex "STOC(G|FH|Mux)?(Asm.*)?$")>; -def : InstRW<[WLat2, FXa, NormalGr], (instregex "SELRMux$")>; -def : InstRW<[WLat2, FXa, NormalGr], (instregex "SEL(G|FH)?R(Asm.*)?$")>; +def : InstRW<[WLat2, FXa, B2BnW, NormalGr], (instregex "SELRMux$")>; +def : InstRW<[WLat2, FXa, B2BnW, NormalGr], (instregex "SEL(G|FH)?R(Asm.*)?$")>; //===----------------------------------------------------------------------===// // Sign extensions //===----------------------------------------------------------------------===// -def : InstRW<[WLat1, FXa, NormalGr], (instregex "L(B|H|G)R$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LG(B|H|F)R$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "L(B|H|G)R$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LG(B|H|F)R$")>; -def : InstRW<[WLat1LSU, WLat1LSU, FXa, LSU, NormalGr], (instregex "LTGF$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LTGFR$")>; +def : InstRW<[WLat1LSU, WLat1LSU, FXa, LSU, B2BnW, NormalGr], + (instregex "LTGF$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LTGFR$")>; -def : InstRW<[WLat1LSU, FXa, LSU, NormalGr], (instregex "LB(H|Mux)?$")>; -def : InstRW<[WLat1LSU, FXa, LSU, NormalGr], (instregex "LH(Y)?$")>; -def : InstRW<[WLat1LSU, FXa, LSU, NormalGr], (instregex "LH(H|Mux|RL)$")>; -def : InstRW<[WLat1LSU, FXa, LSU, NormalGr], (instregex "LG(B|H|F)$")>; -def : InstRW<[WLat1LSU, FXa, LSU, NormalGr], (instregex "LG(H|F)RL$")>; +def : InstRW<[WLat1LSU, FXa, LSU, B2BnW, NormalGr], (instregex "LB(H|Mux)?$")>; +def : InstRW<[WLat1LSU, FXa, LSU, B2BnW, NormalGr], (instregex "LH(Y)?$")>; +def : InstRW<[WLat1LSU, FXa, LSU, B2BnW, NormalGr], (instregex "LH(H|Mux|RL)$")>; +def : InstRW<[WLat1LSU, FXa, LSU, B2BnW, NormalGr], (instregex "LGB$")>; +def : InstRW<[WLat1LSU, FXa, LSU, B2BRW, NormalGr], (instregex "LG(H|F)$")>; +def : InstRW<[WLat1LSU, FXa, LSU, B2BnW, NormalGr], (instregex "LG(H|F)RL$")>; //===----------------------------------------------------------------------===// // Zero extensions //===----------------------------------------------------------------------===// -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LLCR(Mux)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LLHR(Mux)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LLG(C|H|F|T)R$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LLCR(Mux)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LLHR(Mux)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LLG(C|H|F|T)R$")>; def : InstRW<[LSULatency, LSU, NormalGr], (instregex "LLC(Mux)?$")>; def : InstRW<[LSULatency, LSU, NormalGr], (instregex "LLH(Mux)?$")>; -def : InstRW<[WLat1LSU, FXa, LSU, NormalGr], (instregex "LL(C|H)H$")>; +def : InstRW<[WLat1LSU, FXa, LSU, B2BnW, NormalGr], (instregex "LL(C|H)H$")>; def : InstRW<[LSULatency, LSU, NormalGr], (instregex "LLHRL$")>; def : InstRW<[LSULatency, LSU, NormalGr], (instregex "LLG(C|H|F|T|HRL|FRL)$")>; @@ -301,8 +317,8 @@ // Byte swaps //===----------------------------------------------------------------------===// -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LRV(G)?R$")>; -def : InstRW<[WLat1LSU, FXa, LSU, NormalGr], (instregex "LRV(G|H)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LRV(G)?R$")>; +def : InstRW<[WLat1LSU, FXa, LSU, B2BRW, NormalGr], (instregex "LRV(G|H)?$")>; def : InstRW<[WLat1, FXb, LSU, NormalGr], (instregex "STRV(G|H)?$")>; def : InstRW<[WLat30, MCD], (instregex "MVCIN$")>; @@ -310,233 +326,241 @@ // Load address instructions //===----------------------------------------------------------------------===// -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LA(Y|RL)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LA(Y)?$")>; +def : InstRW<[WLat1, FXa, B2BnW, NormalGr], (instregex "LARL?$")>; // Load the Global Offset Table address ( -> larl ) -def : InstRW<[WLat1, FXa, NormalGr], (instregex "GOT$")>; +def : InstRW<[WLat1, FXa, B2BnW, NormalGr], (instregex "GOT$")>; //===----------------------------------------------------------------------===// // Absolute and Negation //===----------------------------------------------------------------------===// -def : InstRW<[WLat1, WLat1, FXa, NormalGr], (instregex "LP(G)?R$")>; -def : InstRW<[WLat2, WLat2, FXa2, Cracked], (instregex "L(N|P)GFR$")>; -def : InstRW<[WLat1, WLat1, FXa, NormalGr], (instregex "LN(R|GR)$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "LC(R|GR)$")>; -def : InstRW<[WLat2, WLat2, FXa2, Cracked], (instregex "LCGFR$")>; +def : InstRW<[WLat1, WLat1, FXa, B2BRW, NormalGr], (instregex "LP(G)?R$")>; +def : InstRW<[WLat2, WLat2, FXa2, B2BRW, Cracked], (instregex "L(N|P)GFR$")>; +def : InstRW<[WLat1, WLat1, FXa, B2BRW, NormalGr], (instregex "LN(R|GR)$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "LC(R|GR)$")>; +def : InstRW<[WLat2, WLat2, FXa2, B2BRW, Cracked], (instregex "LCGFR$")>; //===----------------------------------------------------------------------===// // Insertion //===----------------------------------------------------------------------===// -def : InstRW<[WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], (instregex "IC(Y)?$")>; -def : InstRW<[WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], + (instregex "IC(Y)?$")>; +def : InstRW<[WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "IC32(Y)?$")>; -def : InstRW<[WLat1LSU, RegReadAdv, WLat1LSU, FXa, LSU, NormalGr], +def : InstRW<[WLat1LSU, RegReadAdv, WLat1LSU, FXa, LSU, B2BRW, NormalGr], (instregex "ICM(H|Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "II(F|H|L)Mux$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "IIHF(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "IIHH(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "IIHL(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "IILF(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "IILH(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "IILL(64)?$")>; +def : InstRW<[WLat1, FXa, B2BnW, NormalGr], (instregex "IIFMux$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "II(H|L)Mux$")>; +def : InstRW<[WLat1, FXa, B2BnW, NormalGr], (instregex "IIHF(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "IIHH(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "IIHL(64)?$")>; +def : InstRW<[WLat1, FXa, B2BnW, NormalGr], (instregex "IILF(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "IILH(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "IILL(64)?$")>; //===----------------------------------------------------------------------===// // Addition //===----------------------------------------------------------------------===// -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "A(Y)?$")>; -def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "AH(Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AIH$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AFI(Mux)?$")>; -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AIH$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AFI(Mux)?$")>; +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "AG$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AGFI$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AGHI(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AGR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AHI(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AHIMux(K)?$")>; -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AGFI$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AGHI(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AGR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AHI(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AHIMux(K)?$")>; +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "AL(Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AL(FI|HSIK)$")>; -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AL(FI|HSIK)$")>; +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "ALG(F)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "ALGHSIK$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "ALGF(I|R)$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "ALGR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "ALR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "AR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "A(L)?HHHR$")>; -def : InstRW<[WLat2, WLat2, FXa, NormalGr], (instregex "A(L)?HHLR$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "ALSIH(N)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "ALGHSIK$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "ALGF(I|R)$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "ALGR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "ALR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "AR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "A(L)?HHHR$")>; +def : InstRW<[WLat2, WLat2, FXa, B2BRW, NormalGr], (instregex "A(L)?HHLR$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "ALSIH(N)?$")>; def : InstRW<[WLat2LSU, FXb, LSU, NormalGr], (instregex "A(L)?(G)?SI$")>; // Logical addition with carry -def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, GroupAlone], +def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, B2BnW, GroupAlone], (instregex "ALC(G)?$")>; -def : InstRW<[WLat2, WLat2, FXa, GroupAlone], (instregex "ALC(G)?R$")>; +def : InstRW<[WLat2, WLat2, FXa, B2BnW, GroupAlone], (instregex "ALC(G)?R$")>; // Add with sign extension (16/32 -> 64) -def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "AG(F|H)$")>; -def : InstRW<[WLat2, WLat2, FXa, NormalGr], (instregex "AGFR$")>; +def : InstRW<[WLat2, WLat2, FXa, B2BRW, NormalGr], (instregex "AGFR$")>; //===----------------------------------------------------------------------===// // Subtraction //===----------------------------------------------------------------------===// -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "S(G|Y)?$")>; -def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "SH(Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SGR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SLFI$")>; -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SGR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SLFI$")>; +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "SL(G|GF|Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SLGF(I|R)$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SLGR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SLR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "S(L)?HHHR$")>; -def : InstRW<[WLat2, WLat2, FXa, NormalGr], (instregex "S(L)?HHLR$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SLGF(I|R)$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SLGR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SLR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "S(L)?HHHR$")>; +def : InstRW<[WLat2, WLat2, FXa, B2BRW, NormalGr], (instregex "S(L)?HHLR$")>; // Subtraction with borrow -def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, GroupAlone], +def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, B2BnW, GroupAlone], (instregex "SLB(G)?$")>; -def : InstRW<[WLat2, WLat2, FXa, GroupAlone], (instregex "SLB(G)?R$")>; +def : InstRW<[WLat2, WLat2, FXa, B2BnW, GroupAlone], (instregex "SLB(G)?R$")>; // Subtraction with sign extension (16/32 -> 64) -def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat2LSU, WLat2LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "SG(F|H)$")>; -def : InstRW<[WLat2, WLat2, FXa, NormalGr], (instregex "SGFR$")>; +def : InstRW<[WLat2, WLat2, FXa, B2BRW, NormalGr], (instregex "SGFR$")>; //===----------------------------------------------------------------------===// // AND //===----------------------------------------------------------------------===// -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "N(G|Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NGR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NI(FMux|HMux|LMux)$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NGR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NI(FMux|HMux|LMux)$")>; def : InstRW<[WLat2LSU, FXb, LSU, NormalGr], (instregex "NI(Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NIHF(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NIHH(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NIHL(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NILF(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NILH(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NILL(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NIHF(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NIHH(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NIHL(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NILF(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NILH(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NILL(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NR(K)?$")>; def : InstRW<[WLat3LSU, LSU2, FXb, Cracked], (instregex "NC$")>; //===----------------------------------------------------------------------===// // OR //===----------------------------------------------------------------------===// -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "O(G|Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OGR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OGR(K)?$")>; def : InstRW<[WLat2LSU, FXb, LSU, NormalGr], (instregex "OI(Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OI(FMux|HMux|LMux)$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OIHF(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OIHH(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OIHL(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OILF(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OILH(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OILL(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OI(FMux|HMux|LMux)$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OIHF(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OIHH(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OIHL(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OILF(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OILH(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OILL(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OR(K)?$")>; def : InstRW<[WLat3LSU, LSU2, FXb, Cracked], (instregex "OC$")>; //===----------------------------------------------------------------------===// // XOR //===----------------------------------------------------------------------===// -def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat1LSU, WLat1LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "X(G|Y)?$")>; def : InstRW<[WLat2LSU, FXb, LSU, NormalGr], (instregex "XI(Y)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "XIFMux$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "XGR(K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "XIHF(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "XILF(64)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "XR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "XIFMux$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "XGR(K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "XIHF(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "XILF(64)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "XR(K)?$")>; def : InstRW<[WLat3LSU, LSU2, FXb, Cracked], (instregex "XC$")>; //===----------------------------------------------------------------------===// // Combined logical operations //===----------------------------------------------------------------------===// -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NC(G)?RK$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "OC(G)?RK$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NN(G)?RK$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NO(G)?RK$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "NX(G)?RK$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NC(G)?RK$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "OC(G)?RK$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NN(G)?RK$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NO(G)?RK$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "NX(G)?RK$")>; //===----------------------------------------------------------------------===// // Multiplication //===----------------------------------------------------------------------===// -def : InstRW<[WLat5LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat5LSU, RegReadAdv, FXa, LSU, B2BRn, NormalGr], (instregex "MS(GF|Y)?$")>; -def : InstRW<[WLat5, FXa, NormalGr], (instregex "MS(R|FI)$")>; -def : InstRW<[WLat7LSU, RegReadAdv, FXa, LSU, NormalGr], (instregex "MSG$")>; -def : InstRW<[WLat7, FXa, NormalGr], (instregex "MSGR$")>; -def : InstRW<[WLat5, FXa, NormalGr], (instregex "MSGF(I|R)$")>; -def : InstRW<[WLat8LSU, RegReadAdv, FXa2, LSU, GroupAlone], (instregex "MLG$")>; -def : InstRW<[WLat8, FXa2, GroupAlone], (instregex "MLGR$")>; -def : InstRW<[WLat4, FXa, NormalGr], (instregex "MGHI$")>; -def : InstRW<[WLat4, FXa, NormalGr], (instregex "MHI$")>; -def : InstRW<[WLat4LSU, RegReadAdv, FXa, LSU, NormalGr], (instregex "MH(Y)?$")>; -def : InstRW<[WLat6, FXa2, GroupAlone], (instregex "M(L)?R$")>; -def : InstRW<[WLat6LSU, RegReadAdv, FXa2, LSU, GroupAlone], +def : InstRW<[WLat5, FXa, B2BRn, NormalGr], (instregex "MS(R|FI)$")>; +def : InstRW<[WLat7LSU, RegReadAdv, FXa, LSU, B2BRn, NormalGr], + (instregex "MSG$")>; +def : InstRW<[WLat7, FXa, B2BRn, NormalGr], (instregex "MSGR$")>; +def : InstRW<[WLat5, FXa, B2BRn, NormalGr], (instregex "MSGF(I|R)$")>; +def : InstRW<[WLat8LSU, RegReadAdv, FXa2, LSU, B2BRn, GroupAlone], + (instregex "MLG$")>; +def : InstRW<[WLat8, FXa2, B2BRn, GroupAlone], (instregex "MLGR$")>; +def : InstRW<[WLat4, FXa, B2BRW, NormalGr], (instregex "MGHI$")>; +def : InstRW<[WLat4, FXa, B2BRW, NormalGr], (instregex "MHI$")>; +def : InstRW<[WLat4LSU, RegReadAdv, FXa, LSU, B2BRW, NormalGr], + (instregex "MH(Y)?$")>; +def : InstRW<[WLat6, FXa2, B2BRn, GroupAlone], (instregex "M(L)?R$")>; +def : InstRW<[WLat6LSU, RegReadAdv, FXa2, LSU, B2BRn, GroupAlone], (instregex "M(FY|L)?$")>; -def : InstRW<[WLat8, RegReadAdv, FXa, LSU, NormalGr], (instregex "MGH$")>; -def : InstRW<[WLat12, RegReadAdv, FXa2, LSU, GroupAlone], (instregex "MG$")>; -def : InstRW<[WLat8, FXa2, GroupAlone], (instregex "MGRK$")>; -def : InstRW<[WLat6LSU, WLat6LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat8, RegReadAdv, FXa, LSU, B2BRW, NormalGr], (instregex "MGH$")>; +def : InstRW<[WLat12, RegReadAdv, FXa2, LSU, B2BRn, GroupAlone], + (instregex "MG$")>; +def : InstRW<[WLat8, FXa2, B2BRn, GroupAlone], (instregex "MGRK$")>; +def : InstRW<[WLat6LSU, WLat6LSU, RegReadAdv, FXa, LSU, B2BRn, NormalGr], (instregex "MSC$")>; -def : InstRW<[WLat8LSU, WLat8LSU, RegReadAdv, FXa, LSU, NormalGr], +def : InstRW<[WLat8LSU, WLat8LSU, RegReadAdv, FXa, LSU, B2BRn, NormalGr], (instregex "MSGC$")>; -def : InstRW<[WLat6, WLat6, FXa, NormalGr], (instregex "MSRKC$")>; -def : InstRW<[WLat8, WLat8, FXa, NormalGr], (instregex "MSGRKC$")>; +def : InstRW<[WLat6, WLat6, FXa, B2BRn, NormalGr], (instregex "MSRKC$")>; +def : InstRW<[WLat8, WLat8, FXa, B2BRn, NormalGr], (instregex "MSGRKC$")>; //===----------------------------------------------------------------------===// // Division and remainder //===----------------------------------------------------------------------===// -def : InstRW<[WLat20, FXa4, GroupAlone], (instregex "DR$")>; -def : InstRW<[WLat30, RegReadAdv, FXa4, LSU, GroupAlone2], (instregex "D$")>; -def : InstRW<[WLat30, FXa2, GroupAlone], (instregex "DSG(F)?R$")>; -def : InstRW<[WLat30, RegReadAdv, FXa2, LSU, GroupAlone2], +def : InstRW<[WLat20, FXa4, B2BRn, GroupAlone], (instregex "DR$")>; +def : InstRW<[WLat30, RegReadAdv, FXa4, LSU, B2BRn, GroupAlone2], + (instregex "D$")>; +def : InstRW<[WLat30, FXa2, B2BRn, GroupAlone], (instregex "DSG(F)?R$")>; +def : InstRW<[WLat30, RegReadAdv, FXa2, LSU, B2BRn, GroupAlone2], (instregex "DSG(F)?$")>; -def : InstRW<[WLat20, FXa4, GroupAlone], (instregex "DLR$")>; -def : InstRW<[WLat30, FXa4, GroupAlone], (instregex "DLGR$")>; -def : InstRW<[WLat30, RegReadAdv, FXa4, LSU, GroupAlone2], +def : InstRW<[WLat20, FXa4, B2BRn, GroupAlone], (instregex "DLR$")>; +def : InstRW<[WLat30, FXa4, B2BRn, GroupAlone], (instregex "DLGR$")>; +def : InstRW<[WLat30, RegReadAdv, FXa4, LSU, B2BRn, GroupAlone2], (instregex "DL(G)?$")>; //===----------------------------------------------------------------------===// // Shifts //===----------------------------------------------------------------------===// -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SLL(G|K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SRL(G|K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SRA(G|K)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "SLA(G|K)?$")>; -def : InstRW<[WLat5LSU, WLat5LSU, FXa4, LSU, GroupAlone2], +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SLL(G|K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SRL(G|K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SRA(G|K)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "SLA(G|K)?$")>; +def : InstRW<[WLat5LSU, WLat5LSU, FXa4, LSU, B2BRW, GroupAlone2], (instregex "S(L|R)D(A|L)$")>; // Rotate -def : InstRW<[WLat2LSU, FXa, LSU, NormalGr], (instregex "RLL(G)?$")>; +def : InstRW<[WLat2LSU, FXa, LSU, B2BRW, NormalGr], (instregex "RLL(G)?$")>; // Rotate and insert -def : InstRW<[WLat1, FXa, NormalGr], (instregex "RISBG(N|32)?$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "RISBH(G|H|L)$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "RISBL(G|H|L)$")>; -def : InstRW<[WLat1, FXa, NormalGr], (instregex "RISBMux$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "RISBG(N|32)?$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "RISBH(G|H|L)$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "RISBL(G|H|L)$")>; +def : InstRW<[WLat1, FXa, B2BRW, NormalGr], (instregex "RISBMux$")>; // Rotate and Select -def : InstRW<[WLat2, WLat2, FXa2, Cracked], (instregex "R(N|O|X)SBG$")>; +def : InstRW<[WLat2, WLat2, FXa2, B2BRW, Cracked], (instregex "R(N|O|X)SBG$")>; //===----------------------------------------------------------------------===// // Comparison @@ -630,7 +654,7 @@ (instregex "CS(G|Y)?$")>; // Compare double and swap -def : InstRW<[WLat6LSU, WLat6LSU, FXa3, FXb2, LSU, GroupAlone2], +def : InstRW<[WLat6LSU, WLat6LSU, FXa3, FXb2, LSU, B2BnW, GroupAlone2], (instregex "CDS(Y)?$")>; def : InstRW<[WLat15, WLat15, FXa2, FXb4, LSU3, GroupAlone3], (instregex "CDSG$")>; @@ -725,13 +749,13 @@ //===----------------------------------------------------------------------===// // Insert Program Mask -def : InstRW<[WLat3, FXa, EndGroup], (instregex "IPM$")>; +def : InstRW<[WLat3, FXa, B2BnW, EndGroup], (instregex "IPM$")>; // Set Program Mask def : InstRW<[WLat3, LSU, EndGroup], (instregex "SPM$")>; // Branch and link -def : InstRW<[WLat1, FXa2, FXb, GroupAlone], (instregex "BAL(R)?$")>; +def : InstRW<[WLat1, FXa2, FXb, B2BnW, GroupAlone], (instregex "BAL(R)?$")>; // Test addressing mode def : InstRW<[WLat1, FXb, NormalGr], (instregex "TAM$")>; @@ -740,8 +764,8 @@ def : InstRW<[WLat1, FXb, EndGroup], (instregex "SAM(24|31|64)$")>; // Branch (and save) and set mode. -def : InstRW<[WLat1, FXa, FXb, GroupAlone], (instregex "BSM$")>; -def : InstRW<[WLat1, FXa2, FXb, GroupAlone], (instregex "BASSM$")>; +def : InstRW<[WLat1, FXa, FXb, B2BRW, GroupAlone], (instregex "BSM$")>; +def : InstRW<[WLat1, FXa2, FXb, B2BRW, GroupAlone], (instregex "BASSM$")>; //===----------------------------------------------------------------------===// // Transactional execution @@ -773,10 +797,10 @@ //===----------------------------------------------------------------------===// // Find leftmost one -def : InstRW<[WLat5, WLat5, FXa2, GroupAlone], (instregex "FLOGR$")>; +def : InstRW<[WLat5, WLat5, FXa2, B2BRn, GroupAlone], (instregex "FLOGR$")>; // Population count -def : InstRW<[WLat3, WLat3, FXa, NormalGr], (instregex "POPCNT(Opt)?$")>; +def : InstRW<[WLat3, WLat3, FXa, B2BRW, NormalGr], (instregex "POPCNT(Opt)?$")>; // String instructions def : InstRW<[WLat30, WLat30, WLat30, MCD], (instregex "SRST(U)?$")>; @@ -1547,11 +1571,11 @@ def : InstRW<[WLat30, WLat30, MCD], (instregex "EPSW$")>; def : InstRW<[WLat20, GroupAlone3], (instregex "LPSW(E)?$")>; -def : InstRW<[WLat3, FXa, GroupAlone], (instregex "IPK$")>; +def : InstRW<[WLat3, FXa, B2BRW, GroupAlone], (instregex "IPK$")>; def : InstRW<[WLat1, LSU, EndGroup], (instregex "SPKA$")>; def : InstRW<[WLat1, LSU, EndGroup], (instregex "SSM$")>; def : InstRW<[WLat1, FXb, LSU, GroupAlone], (instregex "ST(N|O)SM$")>; -def : InstRW<[WLat3, FXa, NormalGr], (instregex "IAC$")>; +def : InstRW<[WLat3, FXa, B2BRW, NormalGr], (instregex "IAC$")>; def : InstRW<[WLat1, LSU, EndGroup], (instregex "SAC(F)?$")>; //===----------------------------------------------------------------------===// Index: llvm/test/CodeGen/SystemZ/postra-sched-sidesteer.mir =================================================================== --- /dev/null +++ llvm/test/CodeGen/SystemZ/postra-sched-sidesteer.mir @@ -0,0 +1,109 @@ +# RUN_: llc -mtriple=s390x-linux-gnu -mcpu=z14 -run-pass=postmisched \ +# RUN_: -sidesteer-fxu -sidesteer-lastslot %s -o - 2>&1 | FileCheck %s + +# Alternate method: +# RUN: llc -mtriple=s390x-linux-gnu -mcpu=z14 -run-pass=postmisched \ +# RUN: -sidesteer-fxu -sidesteer-lastslot -sidesteer-lookahead %s -o - 2>&1 | FileCheck %s + +# Test that the last use of r2 ends up on same side as the the def. +--- +# CHECK: name: fun0 +# CHECK-LABEL: bb.0: +# CHECK: $r2d = LGR killed $r0d +# CHECK: $r3d = LGR $r2d +# CHECK: $r4d = LGR $r2d +# CHECK: $r6d = LGR $r5d +# CHECK: $r7d = LGR $r5d +# CHECK: $r8d = LGR killed $r5d +# CHECK: $r0d = LGR $r2d +# CHECK: Return implicit killed $r2d +name: fun0 +machineFunctionInfo: {} +body: | + bb.0: + $r2d = LGR $r0d + $r3d = LGR $r2d + $r4d = LGR $r2d + $r0d = LGR $r2d + $r6d = LGR $r5d + $r7d = LGR $r5d + $r8d = LGR $r5d + Return implicit $r2d +... + + +# Test that the r7 def is not put in the last slot of the decoder group given +# the immediate user of it. +--- +# CHECK: name: fun1 +# CHECK-LABEL: bb.0: +# CHECK: $r2d = LGR killed $r0d +# CHECK: $r2d = LGR killed $r2d +# CHECK: $r4d = LGR killed $r3d +# CHECK: $r7d = LGR killed $r1d +# CHECK: $r8d = LGR killed $r7d +# CHECK: $r6d = LGR killed $r5d +# CHECK: Return implicit killed $r2d + +name: fun1 +machineFunctionInfo: {} +body: | + bb.0: + $r2d = LGR $r0d + $r2d = LGR $r2d + $r4d = LGR $r3d + $r6d = LGR $r5d + $r7d = LGR $r1d + $r8d = LGR $r7d + Return implicit $r2d +... + + +# Test that r4d is put early into decoder group given the immediate user. +--- +# CHECK: name: fun2 +# CHECK-LABEL: bb.0: +# CHECK: $r6d = LGR killed $r7d +# CHECK: $r8d = LGR killed $r6d +# CHECK: $r10d = MSGRKC killed $r8d, $r8d, implicit-def $cc +# CHECK: $r4d = LGR killed $r3d +# CHECK: $r5d = LGR killed $r4d +# CHECK: $r2d = LGR killed $r10d +# CHECK: Return implicit killed $r2d + + name: fun2 + machineFunctionInfo: {} + body: | + bb.0: + $r6d = LGR $r7d + $r4d = LGR $r3d + $r5d = LGR $r4d + $r8d = LGR $r6d + $r10d = MSGRKC $r8d, $r8d, implicit-def $cc + $r2d = LGR $r10d + Return implicit $r2d +... + + +# Test that r6 and r8 are put early into same decoder group as MSGRKC (MSGRKC has other predecessor). +--- +# CHECK: name: fun3 +# CHECK-LABEL: bb.0: +# CHECK: $r6d = LGR killed $r7d +# CHECK: $r8d = LGR killed $r9d +# CHECK: $r10d = MSGRKC killed $r6d, killed $r8d, implicit-def $cc +# CHECK: $r4d = LGR killed $r3d +# CHECK: $r5d = LGR killed $r4d +# CHECK: Return implicit killed $r2d + +name: fun3 +machineFunctionInfo: {} +body: | + bb.0: + $r4d = LGR $r3d + $r6d = LGR $r7d + $r8d = LGR $r9d + $r5d = LGR $r4d + $r10d = MSGRKC $r6d, $r8d, implicit-def $cc + Return implicit $r2d +...