1c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//===-- PPCHazardRecognizers.cpp - PowerPC Hazard Recognizer Impls --------===//
2c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//
3c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//                     The LLVM Compiler Infrastructure
4c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//
8c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//===----------------------------------------------------------------------===//
9c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//
10c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner// This file implements hazard recognizers for scheduling on PowerPC processors.
11c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//
12c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//===----------------------------------------------------------------------===//
13c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
14c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner#include "PPCHazardRecognizers.h"
15c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner#include "PPC.h"
1688d211f82304e53694ece666d4a2507b170e4582Chris Lattner#include "PPCInstrInfo.h"
1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "PPCTargetMachine.h"
18fc54c552963545a81e4ea38e60460590afb2d5aeDan Gohman#include "llvm/CodeGen/ScheduleDAG.h"
19c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner#include "llvm/Support/Debug.h"
20c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h"
21893e1c90a03a53cf13f73849324e83612688428aChris Lattner#include "llvm/Support/raw_ostream.h"
22c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattnerusing namespace llvm;
23c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
24dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "pre-RA-sched"
25dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool PPCDispatchGroupSBHazardRecognizer::isLoadAfterStore(SUnit *SU) {
2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: Move this.
2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (isBCTRAfterSet(SU))
2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!MCID)
3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!MCID->mayLoad())
3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // SU is a load; for any predecessors in this dispatch group, that are stores,
3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // and with which we have an ordering dependency, return true.
4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (unsigned i = 0, ie = (unsigned) SU->Preds.size(); i != ie; ++i) {
4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCInstrDesc *PredMCID = DAG->getInstrDesc(SU->Preds[i].getSUnit());
4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!PredMCID || !PredMCID->mayStore())
4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!SU->Preds[i].isNormalMemory() && !SU->Preds[i].isBarrier())
4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (unsigned j = 0, je = CurGroup.size(); j != je; ++j)
4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (SU->Preds[i].getSUnit() == CurGroup[j])
5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return true;
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool PPCDispatchGroupSBHazardRecognizer::isBCTRAfterSet(SUnit *SU) {
57c6d08f10bf797cc78068ef30bd0e8812a5bdc9a2Hal Finkel  const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
585b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel  if (!MCID)
5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!MCID->isBranch())
6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // SU is a branch; for any predecessors in this dispatch group, with which we
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // have a data dependence and set the counter register, return true.
6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (unsigned i = 0, ie = (unsigned) SU->Preds.size(); i != ie; ++i) {
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCInstrDesc *PredMCID = DAG->getInstrDesc(SU->Preds[i].getSUnit());
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!PredMCID || PredMCID->getSchedClass() != PPC::Sched::IIC_SprMTSPR)
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (SU->Preds[i].isCtrl())
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      continue;
7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (unsigned j = 0, je = CurGroup.size(); j != je; ++j)
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (SU->Preds[i].getSUnit() == CurGroup[j])
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return true;
7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// FIXME: Remove this when we don't need this:
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace llvm { namespace PPC { extern int getNonRecordFormOpcode(uint16_t); } }
8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// FIXME: A lot of code in PPCDispatchGroupSBHazardRecognizer is P7 specific.
8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool PPCDispatchGroupSBHazardRecognizer::mustComeFirst(const MCInstrDesc *MCID,
8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                                       unsigned &NSlots) {
8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: Indirectly, this information is contained in the itinerary, and
9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // we should derive it from there instead of separately specifying it
9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // here.
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned IIC = MCID->getSchedClass();
9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (IIC) {
9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    NSlots = 1;
9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_IntDivW:
9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_IntDivD:
9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_LdStLoadUpd:
10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_LdStLDU:
10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_LdStLFDU:
10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_LdStLFDUX:
10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_LdStLHA:
10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_LdStLHAU:
10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_LdStLWA:
10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_LdStSTDU:
10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_LdStSTFDU:
10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    NSlots = 2;
10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_LdStLoadUpdX:
11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_LdStLDUX:
11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_LdStLHAUX:
11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_LdStLWARX:
11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_LdStLDARX:
11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_LdStSTDUX:
11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_LdStSTDCX:
11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_LdStSTWCX:
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_BrMCRX: // mtcr
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: Add sync/isync (here and in the itinerary).
12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    NSlots = 4;
12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // FIXME: record-form instructions need a different itinerary class.
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (NSlots == 1 && PPC::getNonRecordFormOpcode(MCID->getOpcode()) != -1)
12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    NSlots = 2;
127c6d08f10bf797cc78068ef30bd0e8812a5bdc9a2Hal Finkel
12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (IIC) {
12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // All multi-slot instructions must come first.
13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return NSlots > 1;
13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_BrCR: // cr logicals
13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_SprMFCR:
13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_SprMFCRF:
13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case PPC::Sched::IIC_SprMTSPR:
13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
138c6d08f10bf797cc78068ef30bd0e8812a5bdc9a2Hal Finkel}
139c6d08f10bf797cc78068ef30bd0e8812a5bdc9a2Hal Finkel
1405b00ceaeeabff8c25abb09926343c3fcb06053d8Hal FinkelScheduleHazardRecognizer::HazardType
14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesPPCDispatchGroupSBHazardRecognizer::getHazardType(SUnit *SU, int Stalls) {
14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Stalls == 0 && isLoadAfterStore(SU))
14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return NoopHazard;
14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1455b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel  return ScoreboardHazardRecognizer::getHazardType(SU, Stalls);
1465b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel}
1475b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel
14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool PPCDispatchGroupSBHazardRecognizer::ShouldPreferAnother(SUnit *SU) {
14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned NSlots;
15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (MCID && mustComeFirst(MCID, NSlots) && CurSlots)
15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ScoreboardHazardRecognizer::ShouldPreferAnother(SU);
15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesunsigned PPCDispatchGroupSBHazardRecognizer::PreEmitNoops(SUnit *SU) {
15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // We only need to fill out a maximum of 5 slots here: The 6th slot could
15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // only be a second branch, and otherwise the next instruction will start a
16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // new group.
16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (isLoadAfterStore(SU) && CurSlots < 6) {
16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Directive =
163ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        DAG->MF.getSubtarget<PPCSubtarget>().getDarwinDirective();
16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // If we're using a special group-terminating nop, then we need only one.
165de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // FIXME: the same for P9 as previous gen until POWER9 scheduling is ready
166c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (Directive == PPC::DIR_PWR6 || Directive == PPC::DIR_PWR7 ||
167de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        Directive == PPC::DIR_PWR8 || Directive == PPC::DIR_PWR9)
16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return 1;
16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return 5 - CurSlots;
17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ScoreboardHazardRecognizer::PreEmitNoops(SU);
17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid PPCDispatchGroupSBHazardRecognizer::EmitInstruction(SUnit *SU) {
17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (MCID) {
17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (CurSlots == 5 || (MCID->isBranch() && CurBranches == 1)) {
18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CurGroup.clear();
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CurSlots = CurBranches = 0;
18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else {
18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DEBUG(dbgs() << "**** Adding to dispatch group: SU(" <<
18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                      SU->NodeNum << "): ");
18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DEBUG(DAG->dumpNode(SU));
18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      unsigned NSlots;
18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      bool MustBeFirst = mustComeFirst(MCID, NSlots);
18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // If this instruction must come first, but does not, then it starts a
19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // new group.
19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (MustBeFirst && CurSlots) {
19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        CurSlots = CurBranches = 0;
19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        CurGroup.clear();
19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CurSlots += NSlots;
19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CurGroup.push_back(SU);
19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (MCID->isBranch())
20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        ++CurBranches;
20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ScoreboardHazardRecognizer::EmitInstruction(SU);
20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid PPCDispatchGroupSBHazardRecognizer::AdvanceCycle() {
20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ScoreboardHazardRecognizer::AdvanceCycle();
21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid PPCDispatchGroupSBHazardRecognizer::RecedeCycle() {
21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  llvm_unreachable("Bottom-up scheduling not supported");
21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid PPCDispatchGroupSBHazardRecognizer::Reset() {
21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  CurGroup.clear();
21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  CurSlots = CurBranches = 0;
21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ScoreboardHazardRecognizer::Reset();
2205b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel}
2215b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel
22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid PPCDispatchGroupSBHazardRecognizer::EmitNoop() {
22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Directive =
224ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      DAG->MF.getSubtarget<PPCSubtarget>().getDarwinDirective();
22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // If the group has now filled all of its slots, or if we're using a special
22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // group-terminating nop, the group is complete.
227de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // FIXME: the same for P9 as previous gen until POWER9 scheduling is ready
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Directive == PPC::DIR_PWR6 || Directive == PPC::DIR_PWR7 ||
229de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Directive == PPC::DIR_PWR8 || Directive == PPC::DIR_PWR8 ||
230de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      CurSlots == 6) {
23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CurGroup.clear();
23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CurSlots = CurBranches = 0;
23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else {
234dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CurGroup.push_back(nullptr);
23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ++CurSlots;
23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
2375b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel}
2385b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel
239c6d08f10bf797cc78068ef30bd0e8812a5bdc9a2Hal Finkel//===----------------------------------------------------------------------===//
240c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner// PowerPC 970 Hazard Recognizer
241c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//
2427ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner// This models the dispatch group formation of the PPC970 processor.  Dispatch
24388d211f82304e53694ece666d4a2507b170e4582Chris Lattner// groups are bundles of up to five instructions that can contain various mixes
2446e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick// of instructions.  The PPC970 can dispatch a peak of 4 non-branch and one
24588d211f82304e53694ece666d4a2507b170e4582Chris Lattner// branch instruction per-cycle.
2467ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner//
24788d211f82304e53694ece666d4a2507b170e4582Chris Lattner// There are a number of restrictions to dispatch group formation: some
24888d211f82304e53694ece666d4a2507b170e4582Chris Lattner// instructions can only be issued in the first slot of a dispatch group, & some
24988d211f82304e53694ece666d4a2507b170e4582Chris Lattner// instructions fill an entire dispatch group.  Additionally, only branches can
25088d211f82304e53694ece666d4a2507b170e4582Chris Lattner// issue in the 5th (last) slot.
2517ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner//
2527ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner// Finally, there are a number of "structural" hazards on the PPC970.  These
2537ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner// conditions cause large performance penalties due to misprediction, recovery,
2547ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner// and replay logic that has to happen.  These cases include setting a CTR and
2557ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner// branching through it in the same dispatch group, and storing to an address,
2567ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner// then loading from the same address within a dispatch group.  To avoid these
2577ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner// conditions, we insert no-op instructions when appropriate.
2587ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner//
259c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner// FIXME: This is missing some significant cases:
260c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//   1. Modeling of microcoded instructions.
2613faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner//   2. Handling of serialized operations.
2623faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner//   3. Handling of the esoteric cases in "Resource-based Instruction Grouping".
263c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//
264c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
265c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesPPCHazardRecognizer970::PPCHazardRecognizer970(const ScheduleDAG &DAG)
266c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    : DAG(DAG) {
267b0d21ef20c29f4ea46d21b488f17feaa6a8760e1Chris Lattner  EndDispatchGroup();
268b0d21ef20c29f4ea46d21b488f17feaa6a8760e1Chris Lattner}
269b0d21ef20c29f4ea46d21b488f17feaa6a8760e1Chris Lattner
270c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattnervoid PPCHazardRecognizer970::EndDispatchGroup() {
271893e1c90a03a53cf13f73849324e83612688428aChris Lattner  DEBUG(errs() << "=== Start of dispatch group\n");
272c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  NumIssued = 0;
2736e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
274c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // Structural hazard info.
275c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  HasCTRSet = false;
27688d211f82304e53694ece666d4a2507b170e4582Chris Lattner  NumStores = 0;
277c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
278c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
279c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
2806e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew TrickPPCII::PPC970_Unit
28188d211f82304e53694ece666d4a2507b170e4582Chris LattnerPPCHazardRecognizer970::GetInstrType(unsigned Opcode,
28288d211f82304e53694ece666d4a2507b170e4582Chris Lattner                                     bool &isFirst, bool &isSingle,
2833faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner                                     bool &isCracked,
2843faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner                                     bool &isLoad, bool &isStore) {
285c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  const MCInstrDesc &MCID = DAG.TII->get(Opcode);
2866e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
287e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  isLoad  = MCID.mayLoad();
288e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  isStore = MCID.mayStore();
2896e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
290e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  uint64_t TSFlags = MCID.TSFlags;
2916e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
2923faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  isFirst   = TSFlags & PPCII::PPC970_First;
2933faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  isSingle  = TSFlags & PPCII::PPC970_Single;
2943faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  isCracked = TSFlags & PPCII::PPC970_Cracked;
29588d211f82304e53694ece666d4a2507b170e4582Chris Lattner  return (PPCII::PPC970_Unit)(TSFlags & PPCII::PPC970_Mask);
296c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
297c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
298c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner/// isLoadOfStoredAddress - If we have a load from the previously stored pointer
299c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner/// as indicated by StorePtr1/StorePtr2/StoreSize, return true.
300c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattnerbool PPCHazardRecognizer970::
30164c34e253563a8ba6b41fbce2bb020632cf65961Hal FinkelisLoadOfStoredAddress(uint64_t LoadSize, int64_t LoadOffset,
30264c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  const Value *LoadValue) const {
30388d211f82304e53694ece666d4a2507b170e4582Chris Lattner  for (unsigned i = 0, e = NumStores; i != e; ++i) {
30488d211f82304e53694ece666d4a2507b170e4582Chris Lattner    // Handle exact and commuted addresses.
30564c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    if (LoadValue == StoreValue[i] && LoadOffset == StoreOffset[i])
30688d211f82304e53694ece666d4a2507b170e4582Chris Lattner      return true;
3076e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
30888d211f82304e53694ece666d4a2507b170e4582Chris Lattner    // Okay, we don't have an exact match, if this is an indexed offset, see if
30988d211f82304e53694ece666d4a2507b170e4582Chris Lattner    // we have overlap (which happens during fp->int conversion for example).
31064c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    if (StoreValue[i] == LoadValue) {
31164c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel      // Okay the base pointers match, so we have [c1+r] vs [c2+r].  Check
31264c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel      // to see if the load and store actually overlap.
31364c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel      if (StoreOffset[i] < LoadOffset) {
31464c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel        if (int64_t(StoreOffset[i]+StoreSize[i]) > LoadOffset) return true;
31564c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel      } else {
31664c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel        if (int64_t(LoadOffset+LoadSize) > StoreOffset[i]) return true;
31764c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel      }
31888d211f82304e53694ece666d4a2507b170e4582Chris Lattner    }
319c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  }
320c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  return false;
321c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
322c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
323c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner/// getHazardType - We return hazard for any non-branch instruction that would
324f451cb870efcf9e0302d25ed05f4cac6bb494e42Dan Gohman/// terminate the dispatch group.  We turn NoopHazard for any
325c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner/// instructions that wouldn't terminate the dispatch group that would cause a
326c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner/// pipeline flush.
327fc54c552963545a81e4ea38e60460590afb2d5aeDan GohmanScheduleHazardRecognizer::HazardType PPCHazardRecognizer970::
3282da8bc8a5f7705ac131184cd247f48500da0d74eAndrew TrickgetHazardType(SUnit *SU, int Stalls) {
3292da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick  assert(Stalls == 0 && "PPC hazards don't support scoreboard lookahead");
3302da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick
33164c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  MachineInstr *MI = SU->getInstr();
33264c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel
33364c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  if (MI->isDebugValue())
33464c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    return NoHazard;
33564c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel
33664c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  unsigned Opcode = MI->getOpcode();
3373faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  bool isFirst, isSingle, isCracked, isLoad, isStore;
3386e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick  PPCII::PPC970_Unit InstrType =
33964c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    GetInstrType(Opcode, isFirst, isSingle, isCracked,
3403faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner                 isLoad, isStore);
3416e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick  if (InstrType == PPCII::PPC970_Pseudo) return NoHazard;
342c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
34388d211f82304e53694ece666d4a2507b170e4582Chris Lattner  // We can only issue a PPC970_First/PPC970_Single instruction (such as
34488d211f82304e53694ece666d4a2507b170e4582Chris Lattner  // crand/mtspr/etc) if this is the first cycle of the dispatch group.
3453faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  if (NumIssued != 0 && (isFirst || isSingle))
34688d211f82304e53694ece666d4a2507b170e4582Chris Lattner    return Hazard;
3476e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
3483faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  // If this instruction is cracked into two ops by the decoder, we know that
3493faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  // it is not a branch and that it cannot issue if 3 other instructions are
3503faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  // already in the dispatch group.
3513faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  if (isCracked && NumIssued > 2)
3523faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner    return Hazard;
3536e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
354c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  switch (InstrType) {
355c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown instruction type!");
35688d211f82304e53694ece666d4a2507b170e4582Chris Lattner  case PPCII::PPC970_FXU:
35788d211f82304e53694ece666d4a2507b170e4582Chris Lattner  case PPCII::PPC970_LSU:
35888d211f82304e53694ece666d4a2507b170e4582Chris Lattner  case PPCII::PPC970_FPU:
35988d211f82304e53694ece666d4a2507b170e4582Chris Lattner  case PPCII::PPC970_VALU:
36088d211f82304e53694ece666d4a2507b170e4582Chris Lattner  case PPCII::PPC970_VPERM:
36188d211f82304e53694ece666d4a2507b170e4582Chris Lattner    // We can only issue a branch as the last instruction in a group.
36288d211f82304e53694ece666d4a2507b170e4582Chris Lattner    if (NumIssued == 4) return Hazard;
36388d211f82304e53694ece666d4a2507b170e4582Chris Lattner    break;
36488d211f82304e53694ece666d4a2507b170e4582Chris Lattner  case PPCII::PPC970_CRU:
36588d211f82304e53694ece666d4a2507b170e4582Chris Lattner    // We can only issue a CR instruction in the first two slots.
36688d211f82304e53694ece666d4a2507b170e4582Chris Lattner    if (NumIssued >= 2) return Hazard;
36788d211f82304e53694ece666d4a2507b170e4582Chris Lattner    break;
36888d211f82304e53694ece666d4a2507b170e4582Chris Lattner  case PPCII::PPC970_BRU:
36988d211f82304e53694ece666d4a2507b170e4582Chris Lattner    break;
370c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  }
3716e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
372c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // Do not allow MTCTR and BCTRL to be in the same dispatch group.
37386765fbe170198e7bb40fd8499d1354f4c786f60Ulrich Weigand  if (HasCTRSet && Opcode == PPC::BCTRL)
374c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    return NoopHazard;
3756e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
376c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // If this is a load following a store, make sure it's not to the same or
377c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // overlapping address.
37864c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  if (isLoad && NumStores && !MI->memoperands_empty()) {
37964c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    MachineMemOperand *MO = *MI->memoperands_begin();
38064c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    if (isLoadOfStoredAddress(MO->getSize(),
38164c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel                              MO->getOffset(), MO->getValue()))
382c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner      return NoopHazard;
383c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  }
3846e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
385c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  return NoHazard;
386c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
387c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
388fc54c552963545a81e4ea38e60460590afb2d5aeDan Gohmanvoid PPCHazardRecognizer970::EmitInstruction(SUnit *SU) {
38964c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  MachineInstr *MI = SU->getInstr();
39064c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel
39164c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  if (MI->isDebugValue())
39264c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    return;
39364c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel
39464c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  unsigned Opcode = MI->getOpcode();
3953faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  bool isFirst, isSingle, isCracked, isLoad, isStore;
3966e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick  PPCII::PPC970_Unit InstrType =
39764c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    GetInstrType(Opcode, isFirst, isSingle, isCracked,
3983faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner                 isLoad, isStore);
3996e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick  if (InstrType == PPCII::PPC970_Pseudo) return;
400c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
401c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // Update structural hazard information.
4020c9b559bfd0b476c2dde787285a1195f3142c423Roman Divacky  if (Opcode == PPC::MTCTR || Opcode == PPC::MTCTR8) HasCTRSet = true;
4036e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
404c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // Track the address stored to.
40564c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  if (isStore && NumStores < 4 && !MI->memoperands_empty()) {
40664c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    MachineMemOperand *MO = *MI->memoperands_begin();
40764c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    StoreSize[NumStores] = MO->getSize();
40864c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    StoreOffset[NumStores] = MO->getOffset();
40964c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    StoreValue[NumStores] = MO->getValue();
41088d211f82304e53694ece666d4a2507b170e4582Chris Lattner    ++NumStores;
411c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  }
4126e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
41388d211f82304e53694ece666d4a2507b170e4582Chris Lattner  if (InstrType == PPCII::PPC970_BRU || isSingle)
41488d211f82304e53694ece666d4a2507b170e4582Chris Lattner    NumIssued = 4;  // Terminate a d-group.
415c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  ++NumIssued;
4166e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
4173faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  // If this instruction is cracked into two ops by the decoder, remember that
4183faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  // we issued two pieces.
4193faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  if (isCracked)
4203faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner    ++NumIssued;
4216e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
422c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  if (NumIssued == 5)
423c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    EndDispatchGroup();
424c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
425c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
426c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattnervoid PPCHazardRecognizer970::AdvanceCycle() {
427c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  assert(NumIssued < 5 && "Illegal dispatch group!");
428c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  ++NumIssued;
429c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  if (NumIssued == 5)
430c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    EndDispatchGroup();
431c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
43264c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel
43364c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkelvoid PPCHazardRecognizer970::Reset() {
43464c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  EndDispatchGroup();
43564c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel}
43664c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel
437