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 @@ -84,9 +86,41 @@ /// the cycle index of the next group. unsigned getCurrCycleIdx(SUnit *SU = nullptr) const; - /// LastFPdOpCycleIdx stores the numbeer returned by getCurrCycleIdx() - /// 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 }; + 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 isB2BOp(SUnit *SU, unsigned Idx, bool Def) const; + bool isCountedProcResource(unsigned PIdx) const { + return !(PIdx == ProcRes::B2BRW || PIdx == ProcRes::B2BRn || + PIdx == ProcRes::B2BnW); + } + + /// Map from a side steered resource to its previous cycle index. This is + /// the number returned by getCurrCycleIdx(), and is used when the next SU + /// using the same resource is to be scheduled preferrably either on same + /// (FXU) or opposite (FPd) side. + std::vector SideSteerIndexes; + + /// Each physical register number is its own side steer ID, so the next ID + /// gets the next higher number. + unsigned const FPdID = SystemZ::NUM_TARGET_REGS; + + /// Given SU, returns an index into the SideSteerIndexes vector, or + /// UINT_MAX if SU does not touch a side steered resource. This could be a + /// defined register or a used functional unit. + unsigned getSideSteerResourceID(SUnit *SU) const; + + /// Returns true if it is believed that the side steered resource given by + // ID was scheduled on the same processor side (or opposide if SameSide is + // false) as SU will be placed on. + bool checkSide(unsigned ID, bool SameSide, SUnit *SU) const; /// A counter of decoder groups scheduled. unsigned GrpCount; @@ -108,9 +142,23 @@ public: SystemZHazardRecognizer(const SystemZInstrInfo *tii, + const TargetRegisterInfo *tri, const TargetSchedModel *SM) - : TII(tii), SchedModel(SM) { + : TII(tii), TRI(tri), SchedModel(SM) { + SideSteerIndexes.resize(SystemZ::NUM_TARGET_REGS + 1/*FPd*/, UINT_MAX); 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"); +#endif } HazardType getHazardType(SUnit *SU, int Stalls = 0) override; @@ -141,12 +189,15 @@ /// a negative value means it would be good to schedule SU next. int resourcesCost(SUnit *SU); + int bypassCost(SUnit *SU) const; + #ifndef NDEBUG // Debug dumping. std::string CurGroupDbg; // current group as text void dumpSU(SUnit *SU, raw_ostream &OS) const; void dumpCurrGroup(std::string Msg = "") const; void dumpProcResourceCounters() const; + void dumpSideIndexes(std::string Msg = "") const; void dumpState() const; #endif 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 +static cl::opt NewFPDSideSteer("newfpd-sides", cl::init(false)); +static cl::opt SideSteerExact("sidesteer-exact", cl::init(false)); + unsigned SystemZHazardRecognizer:: getNumDecoderSlots(SUnit *SU) const { const MCSchedClassDesc *SC = getSchedClass(SU); @@ -73,6 +77,61 @@ return Idx; } +static bool isFXUReg(const MachineOperand &MO) { + return (SystemZ::GRX32BitRegClass.contains(MO.getReg()) || + SystemZ::GR64BitRegClass.contains(MO.getReg()) || + SystemZ::GR128BitRegClass.contains(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::isB2BOp(SUnit *SU, unsigned Idx, bool Def) const { + MachineInstr *MI = SU->getInstr(); + 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))); +} + +unsigned SystemZHazardRecognizer:: +getSideSteerResourceID(SUnit *SU) const { + if (SU->isUnbuffered) + return FPdID; + + const MachineInstr *MI = SU->getInstr(); + return (MI->getNumOperands() && + isB2BOp(SU, 0, true/*Def*/)) ? ((unsigned) MI->getOperand(0).getReg()) + : UINT_MAX; +} + +bool SystemZHazardRecognizer:: +checkSide(unsigned ID, bool SameSide, SUnit *SU) const { + unsigned PrevIdx = SideSteerIndexes[ID]; + if (PrevIdx == UINT_MAX) + return false; + unsigned CurrIdx = getCurrCycleIdx(SU); + + if (SideSteerExact) { + return ((SameSide && CurrIdx == PrevIdx) || + (!SameSide && std::abs(((int) CurrIdx) - ((int) PrevIdx)) == 3)); + } + bool CurrLow = CurrIdx < 3; + bool PrevLow = PrevIdx < 3; + return ((SameSide && (CurrLow == PrevLow)) || + (!SameSide && (CurrLow != PrevLow))); +} + ScheduleHazardRecognizer::HazardType SystemZHazardRecognizer:: getHazardType(SUnit *SU, int Stalls) { return (fitsIntoCurrentGroup(SU) ? NoHazard : Hazard); @@ -83,8 +142,8 @@ CurrGroupHas4RegOps = false; clearProcResCounters(); GrpCount = 0; - LastFPdOpCycleIdx = UINT_MAX; LastEmittedMI = nullptr; + SideSteerIndexes.assign(SideSteerIndexes.size(), UINT_MAX); LLVM_DEBUG(CurGroupDbg = "";); } @@ -165,8 +224,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 +235,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 +263,19 @@ OS << "/EndsGroup"; if (SU->isUnbuffered) OS << "/Unbuffered"; - if (has4RegOps(SU->getInstr())) + if (has4RegOps(MI)) OS << "/4RegOps"; + + unsigned ID = getSideSteerResourceID(SU); + if (ID != UINT_MAX) { + OS << "/" << getSideSteerResourceName(ID); + if (ID < SystemZ::NUM_TARGET_REGS) + OS << ":B2BW"; + } + + for (unsigned Idx = 0; Idx < MI->getNumOperands(); ++Idx) + if (isB2BOp(SU, Idx, false/*Def*/)) + OS << "/" << TRI->getName(MI->getOperand(Idx).getReg()) << ":B2BR"; } void SystemZHazardRecognizer::dumpCurrGroup(std::string Msg) const { @@ -245,15 +318,53 @@ << "\n"; } +void SystemZHazardRecognizer:: +dumpSideIndexes(std::string Msg) const { + bool any = false; + for (unsigned I : SideSteerIndexes) + if (I != UINT_MAX) { + any = true; + break; + } + if (!any) + return; + + dbgs() << "++ | " << Msg; + bool First = true; + unsigned ColCount = 0, RowCount = 0; + for (unsigned i = 0; i < SideSteerIndexes.size() ; i++) { + if (SideSteerIndexes[i] == UINT_MAX) + continue; + if (!First) + dbgs() << ", "; + else + First = false; + dbgs() << getSideSteerResourceName(i) << ":" << SideSteerIndexes[i]; + if ((++ColCount == 8 && !RowCount) || (ColCount == 13 && RowCount)) { + dbgs() << ",\n++ | "; + ColCount = 0; + RowCount++; + First = true; + } + } + dbgs() << ".\n"; +} + void SystemZHazardRecognizer::dumpState() const { dumpCurrGroup("| Current decoder group"); dbgs() << "++ | Current cycle index: " << getCurrCycleIdx() << "\n"; dumpProcResourceCounters(); - if (LastFPdOpCycleIdx != UINT_MAX) - dbgs() << "++ | Last FPd cycle index: " << LastFPdOpCycleIdx << "\n"; + dumpSideIndexes("Last side steered resource cycle indexes: "); } +std::string SystemZHazardRecognizer:: +getSideSteerResourceName(unsigned ID) const { + assert (ID < SideSteerIndexes.size() && "Invalid ID"); + if (ID == FPdID) + return "FPd"; + return TRI->getName(ID); +} #endif //NDEBUG void SystemZHazardRecognizer::clearProcResCounters() { @@ -299,6 +410,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; @@ -316,11 +429,27 @@ } } - // Make note of an instruction that uses a blocking resource (FPd). - if (SU->isUnbuffered) { - LastFPdOpCycleIdx = getCurrCycleIdx(SU); - LLVM_DEBUG(dbgs() << "++ Last FPd cycle index: " << LastFPdOpCycleIdx - << "\n";); + // Remember the cycle index of SU for its side steered resource. + unsigned SUIdx = getCurrCycleIdx(SU); + unsigned ID = getSideSteerResourceID(SU); + MachineInstr *MI = SU->getInstr(); + if (ID == UINT_MAX && MI->getNumOperands()) { + // Clear entry in case of a non-FXa write. + const MachineOperand &MO = MI->getOperand(0); + if (MO.isReg() && MO.isDef() && !MO.isImplicit() && isFXUReg(MO)) { + ID = MO.getReg(); + SUIdx = UINT_MAX; + } + } + if (ID != UINT_MAX) { + if (ID < SystemZ::NUM_TARGET_REGS) { + // TODO: Is it relevant to handle high/low subregs separately? + for (MCRegAliasIterator AI(ID, TRI, /*IncludeSelf=*/true); + AI.isValid(); ++AI) + SideSteerIndexes[*AI] = SUIdx; + } + else + SideSteerIndexes[ID] = SUIdx; } // Insert SU into current group by increasing number of slots used @@ -370,17 +499,26 @@ bool SystemZHazardRecognizer::isFPdOpPreferred_distance(SUnit *SU) const { assert (SU->isUnbuffered); - // If this is the first FPd op, it should be scheduled high. - if (LastFPdOpCycleIdx == UINT_MAX) - return true; - // If this is not the first PFd op, it should go into the other side - // of the processor to use the other FPd unit there. This should - // generally happen if two FPd ops are placed with 2 other - // instructions between them (modulo 6). - unsigned SUCycleIdx = getCurrCycleIdx(SU); - if (LastFPdOpCycleIdx > SUCycleIdx) - return ((LastFPdOpCycleIdx - SUCycleIdx) == 3); - return ((SUCycleIdx - LastFPdOpCycleIdx) == 3); + + if (!NewFPDSideSteer) { + // If this is the first FPd op, it should be scheduled high. + if (SideSteerIndexes[FPdID] == UINT_MAX) + return true; + // If this is not the first PFd op, it should go into the other side + // of the processor to use the other FPd unit there. This should + // generally happen if two FPd ops are placed with 2 other + // instructions between them (modulo 6). + unsigned SUCycleIdx = getCurrCycleIdx(SU); + if (SideSteerIndexes[FPdID] > SUCycleIdx) + return ((SideSteerIndexes[FPdID] - SUCycleIdx) == 3); + return ((SUCycleIdx - SideSteerIndexes[FPdID]) == 3); + } + + // If this is the first FPd op it should be scheduled high, otherwise it + // should preferrably go to the other processor side and so use the + // alternate FPd unit. + return ((SideSteerIndexes[FPdID] == UINT_MAX) || + checkSide(FPdID, false/*SameSide*/, SU)); } int SystemZHazardRecognizer:: @@ -407,6 +545,63 @@ return Cost; } +// EXPERIMENTAL +#include "llvm/Support/CommandLine.h" +static cl::opt SIDESTEERING_LASTSLOT("sidesteer-lastslot", cl::init(false)); + +int SystemZHazardRecognizer::bypassCost(SUnit *SU) const { + MachineInstr *MI = SU->getInstr(); + + // Put FXU register use on same side as previous def. + int RegsSameSide = 0; + int RegsOppositeSide = 0; + for (unsigned Idx = 0; Idx < MI->getNumOperands(); ++Idx) { + MachineOperand &MO = MI->getOperand(Idx); + if (isB2BOp(SU, Idx, false/*Def*/)) { + if (checkSide(MO.getReg(), true/*SameSide*/, SU)) + RegsSameSide++; + else if (checkSide(MO.getReg(), false/*SameSide*/, SU)) + RegsOppositeSide++; + } + } + + int Cost = RegsOppositeSide - RegsSameSide; + if (Cost != 0) + return Cost > 0 ? Cost + 1 : Cost - 1; + + // Give an immediate user a chance into the same decoder group. + unsigned DefedFXUReg = getSideSteerResourceID(SU); + if (DefedFXUReg < SystemZ::NUM_TARGET_REGS && SIDESTEERING_LASTSLOT) { + unsigned CurrIdx = getCurrCycleIdx(SU); + bool OnLastSlot = (CurrIdx == 2 || CurrIdx == 5); + // If CurrIdx is the last slot in group and SU has a successor that is + // only waiting for DefedFXUReg, return a positive cost. + for (SDep &SuccDep : SU->Succs) { + SUnit *SuccSU = SuccDep.getSUnit(); + if (SuccDep.getKind() != SDep::Data || SuccSU->isBoundaryNode()) + continue; + bool OnlyWaitingForSU = true; + for (SDep &SuccPred : SuccSU->Preds) { + SUnit *SPSU = SuccPred.getSUnit(); + if (!SPSU->isBoundaryNode() && !SPSU->isScheduled && SPSU != SU) { + OnlyWaitingForSU = false; + break; + } + } + if (!OnlyWaitingForSU) + continue; + + MachineInstr *SuccMI = SuccSU->getInstr(); + for (unsigned Idx = 0; Idx < SuccMI->getNumOperands(); ++Idx) + if (isB2BOp(SuccSU, Idx, false/*Def*/) && + TRI->regsOverlap(SuccMI->getOperand(Idx).getReg(), DefedFXUReg)) + return OnLastSlot ? 1 : -1; + } + } + + return 0; +} + void SystemZHazardRecognizer::emitInstruction(MachineInstr *MI, bool TakenBranch) { // Make a temporary SUnit. @@ -457,7 +652,7 @@ ProcResourceCounters = Incoming->ProcResourceCounters; CriticalResourceIdx = Incoming->CriticalResourceIdx; - // FPd - LastFPdOpCycleIdx = Incoming->LastFPdOpCycleIdx; GrpCount = Incoming->GrpCount; + + SideSteerIndexes = Incoming->SideSteerIndexes; } 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) cost of side steering of GR registers. + int BypassCost = 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 (BypassCost <= -3 || 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 (BypassCost != 0) + dbgs() << " BypassCost:" << BypassCost; } #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; @@ -81,18 +82,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; @@ -130,6 +132,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); @@ -173,6 +176,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. @@ -189,7 +193,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; } @@ -197,6 +201,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_; @@ -208,6 +216,10 @@ // Check the resources cost for this SU. ResourcesCost = HazardRec.resourcesCost(SU); + + // Side steering + if (SIDESTEERING_FXU) + BypassCost = HazardRec.bypassCost(SU); } bool SystemZPostRASchedStrategy::Candidate:: @@ -225,6 +237,14 @@ if (ResourcesCost > other.ResourcesCost) return false; + // Try to help FXU bypassing. + if (true /*heightdiff / cutoff ??*/) { + if (BypassCost < other.BypassCost) + return true; + if (BypassCost > other.BypassCost) + return false; + } + // Higher SU is otherwise generally better. if (SU->getHeight() > other.SU->getHeight()) return true; 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,79 @@ +# RUN: llc -mtriple=s390x-linux-gnu -mcpu=z14 -run-pass=postmisched \ +# RUN: -sidesteer-fxu -sidesteer-lastslot %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: $r4d = LGR killed $r3d +# CHECK: $r5d = LGR killed $r4d +# CHECK: $r6d = LGR killed $r7d +# CHECK: $r8d = LGR killed $r9d +# CHECK: $r10d = MSGRKC killed $r6d, killed $r8d, implicit-def $cc +# CHECK: Return implicit killed $r2d + +name: fun2 +machineFunctionInfo: {} +body: | + bb.0: + $r6d = LGR $r7d + $r8d = LGR $r9d + $r4d = LGR $r3d + $r5d = LGR $r4d + $r10d = MSGRKC $r6d, $r8d, implicit-def $cc + Return implicit $r2d +...