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 =
16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DAG->TM.getSubtarget<PPCSubtarget>().getDarwinDirective();
16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // If we're using a special group-terminating nop, then we need only one.
165cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Directive == PPC::DIR_PWR6 || Directive == PPC::DIR_PWR7 ||
166cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        Directive == PPC::DIR_PWR8 )
16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return 1;
16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return 5 - CurSlots;
17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ScoreboardHazardRecognizer::PreEmitNoops(SU);
17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid PPCDispatchGroupSBHazardRecognizer::EmitInstruction(SUnit *SU) {
17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCInstrDesc *MCID = DAG->getInstrDesc(SU);
17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (MCID) {
17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (CurSlots == 5 || (MCID->isBranch() && CurBranches == 1)) {
17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CurGroup.clear();
18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CurSlots = CurBranches = 0;
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else {
18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DEBUG(dbgs() << "**** Adding to dispatch group: SU(" <<
18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                      SU->NodeNum << "): ");
18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DEBUG(DAG->dumpNode(SU));
18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      unsigned NSlots;
18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      bool MustBeFirst = mustComeFirst(MCID, NSlots);
18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // If this instruction must come first, but does not, then it starts a
19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // new group.
19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (MustBeFirst && CurSlots) {
19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        CurSlots = CurBranches = 0;
19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        CurGroup.clear();
19436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
19636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CurSlots += NSlots;
19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CurGroup.push_back(SU);
19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (MCID->isBranch())
20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        ++CurBranches;
20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ScoreboardHazardRecognizer::EmitInstruction(SU);
20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid PPCDispatchGroupSBHazardRecognizer::AdvanceCycle() {
20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ScoreboardHazardRecognizer::AdvanceCycle();
20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid PPCDispatchGroupSBHazardRecognizer::RecedeCycle() {
21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  llvm_unreachable("Bottom-up scheduling not supported");
21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid PPCDispatchGroupSBHazardRecognizer::Reset() {
21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  CurGroup.clear();
21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  CurSlots = CurBranches = 0;
21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ScoreboardHazardRecognizer::Reset();
2195b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel}
2205b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel
22136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid PPCDispatchGroupSBHazardRecognizer::EmitNoop() {
22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Directive =
22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DAG->TM.getSubtarget<PPCSubtarget>().getDarwinDirective();
22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // If the group has now filled all of its slots, or if we're using a special
22536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // group-terminating nop, the group is complete.
22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Directive == PPC::DIR_PWR6 || Directive == PPC::DIR_PWR7 ||
227cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Directive == PPC::DIR_PWR8 || CurSlots == 6)  {
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CurGroup.clear();
22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CurSlots = CurBranches = 0;
23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else {
231dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    CurGroup.push_back(nullptr);
23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    ++CurSlots;
23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
2345b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel}
2355b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel
236c6d08f10bf797cc78068ef30bd0e8812a5bdc9a2Hal Finkel//===----------------------------------------------------------------------===//
237c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner// PowerPC 970 Hazard Recognizer
238c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//
2397ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner// This models the dispatch group formation of the PPC970 processor.  Dispatch
24088d211f82304e53694ece666d4a2507b170e4582Chris Lattner// groups are bundles of up to five instructions that can contain various mixes
2416e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick// of instructions.  The PPC970 can dispatch a peak of 4 non-branch and one
24288d211f82304e53694ece666d4a2507b170e4582Chris Lattner// branch instruction per-cycle.
2437ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner//
24488d211f82304e53694ece666d4a2507b170e4582Chris Lattner// There are a number of restrictions to dispatch group formation: some
24588d211f82304e53694ece666d4a2507b170e4582Chris Lattner// instructions can only be issued in the first slot of a dispatch group, & some
24688d211f82304e53694ece666d4a2507b170e4582Chris Lattner// instructions fill an entire dispatch group.  Additionally, only branches can
24788d211f82304e53694ece666d4a2507b170e4582Chris Lattner// issue in the 5th (last) slot.
2487ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner//
2497ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner// Finally, there are a number of "structural" hazards on the PPC970.  These
2507ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner// conditions cause large performance penalties due to misprediction, recovery,
2517ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner// and replay logic that has to happen.  These cases include setting a CTR and
2527ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner// branching through it in the same dispatch group, and storing to an address,
2537ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner// then loading from the same address within a dispatch group.  To avoid these
2547ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner// conditions, we insert no-op instructions when appropriate.
2557ce64852e8fc260f8a7434217c1b57b85a70a1c8Chris Lattner//
256c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner// FIXME: This is missing some significant cases:
257c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//   1. Modeling of microcoded instructions.
2583faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner//   2. Handling of serialized operations.
2593faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner//   3. Handling of the esoteric cases in "Resource-based Instruction Grouping".
260c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner//
261c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
262cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesPPCHazardRecognizer970::PPCHazardRecognizer970(const ScheduleDAG &DAG)
263cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    : DAG(DAG) {
264b0d21ef20c29f4ea46d21b488f17feaa6a8760e1Chris Lattner  EndDispatchGroup();
265b0d21ef20c29f4ea46d21b488f17feaa6a8760e1Chris Lattner}
266b0d21ef20c29f4ea46d21b488f17feaa6a8760e1Chris Lattner
267c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattnervoid PPCHazardRecognizer970::EndDispatchGroup() {
268893e1c90a03a53cf13f73849324e83612688428aChris Lattner  DEBUG(errs() << "=== Start of dispatch group\n");
269c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  NumIssued = 0;
2706e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
271c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // Structural hazard info.
272c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  HasCTRSet = false;
27388d211f82304e53694ece666d4a2507b170e4582Chris Lattner  NumStores = 0;
274c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
275c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
276c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
2776e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew TrickPPCII::PPC970_Unit
27888d211f82304e53694ece666d4a2507b170e4582Chris LattnerPPCHazardRecognizer970::GetInstrType(unsigned Opcode,
27988d211f82304e53694ece666d4a2507b170e4582Chris Lattner                                     bool &isFirst, bool &isSingle,
2803faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner                                     bool &isCracked,
2813faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner                                     bool &isLoad, bool &isStore) {
282cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const MCInstrDesc &MCID = DAG.TII->get(Opcode);
2836e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
284e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  isLoad  = MCID.mayLoad();
285e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  isStore = MCID.mayStore();
2866e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
287e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  uint64_t TSFlags = MCID.TSFlags;
2886e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
2893faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  isFirst   = TSFlags & PPCII::PPC970_First;
2903faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  isSingle  = TSFlags & PPCII::PPC970_Single;
2913faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  isCracked = TSFlags & PPCII::PPC970_Cracked;
29288d211f82304e53694ece666d4a2507b170e4582Chris Lattner  return (PPCII::PPC970_Unit)(TSFlags & PPCII::PPC970_Mask);
293c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
294c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
295c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner/// isLoadOfStoredAddress - If we have a load from the previously stored pointer
296c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner/// as indicated by StorePtr1/StorePtr2/StoreSize, return true.
297c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattnerbool PPCHazardRecognizer970::
29864c34e253563a8ba6b41fbce2bb020632cf65961Hal FinkelisLoadOfStoredAddress(uint64_t LoadSize, int64_t LoadOffset,
29964c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  const Value *LoadValue) const {
30088d211f82304e53694ece666d4a2507b170e4582Chris Lattner  for (unsigned i = 0, e = NumStores; i != e; ++i) {
30188d211f82304e53694ece666d4a2507b170e4582Chris Lattner    // Handle exact and commuted addresses.
30264c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    if (LoadValue == StoreValue[i] && LoadOffset == StoreOffset[i])
30388d211f82304e53694ece666d4a2507b170e4582Chris Lattner      return true;
3046e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
30588d211f82304e53694ece666d4a2507b170e4582Chris Lattner    // Okay, we don't have an exact match, if this is an indexed offset, see if
30688d211f82304e53694ece666d4a2507b170e4582Chris Lattner    // we have overlap (which happens during fp->int conversion for example).
30764c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    if (StoreValue[i] == LoadValue) {
30864c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel      // Okay the base pointers match, so we have [c1+r] vs [c2+r].  Check
30964c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel      // to see if the load and store actually overlap.
31064c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel      if (StoreOffset[i] < LoadOffset) {
31164c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel        if (int64_t(StoreOffset[i]+StoreSize[i]) > LoadOffset) return true;
31264c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel      } else {
31364c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel        if (int64_t(LoadOffset+LoadSize) > StoreOffset[i]) return true;
31464c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel      }
31588d211f82304e53694ece666d4a2507b170e4582Chris Lattner    }
316c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  }
317c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  return false;
318c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
319c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
320c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner/// getHazardType - We return hazard for any non-branch instruction that would
321f451cb870efcf9e0302d25ed05f4cac6bb494e42Dan Gohman/// terminate the dispatch group.  We turn NoopHazard for any
322c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner/// instructions that wouldn't terminate the dispatch group that would cause a
323c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner/// pipeline flush.
324fc54c552963545a81e4ea38e60460590afb2d5aeDan GohmanScheduleHazardRecognizer::HazardType PPCHazardRecognizer970::
3252da8bc8a5f7705ac131184cd247f48500da0d74eAndrew TrickgetHazardType(SUnit *SU, int Stalls) {
3262da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick  assert(Stalls == 0 && "PPC hazards don't support scoreboard lookahead");
3272da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick
32864c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  MachineInstr *MI = SU->getInstr();
32964c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel
33064c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  if (MI->isDebugValue())
33164c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    return NoHazard;
33264c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel
33364c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  unsigned Opcode = MI->getOpcode();
3343faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  bool isFirst, isSingle, isCracked, isLoad, isStore;
3356e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick  PPCII::PPC970_Unit InstrType =
33664c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    GetInstrType(Opcode, isFirst, isSingle, isCracked,
3373faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner                 isLoad, isStore);
3386e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick  if (InstrType == PPCII::PPC970_Pseudo) return NoHazard;
339c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
34088d211f82304e53694ece666d4a2507b170e4582Chris Lattner  // We can only issue a PPC970_First/PPC970_Single instruction (such as
34188d211f82304e53694ece666d4a2507b170e4582Chris Lattner  // crand/mtspr/etc) if this is the first cycle of the dispatch group.
3423faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  if (NumIssued != 0 && (isFirst || isSingle))
34388d211f82304e53694ece666d4a2507b170e4582Chris Lattner    return Hazard;
3446e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
3453faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  // If this instruction is cracked into two ops by the decoder, we know that
3463faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  // it is not a branch and that it cannot issue if 3 other instructions are
3473faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  // already in the dispatch group.
3483faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  if (isCracked && NumIssued > 2)
3493faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner    return Hazard;
3506e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
351c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  switch (InstrType) {
352c23197a26f34f559ea9797de51e187087c039c42Torok Edwin  default: llvm_unreachable("Unknown instruction type!");
35388d211f82304e53694ece666d4a2507b170e4582Chris Lattner  case PPCII::PPC970_FXU:
35488d211f82304e53694ece666d4a2507b170e4582Chris Lattner  case PPCII::PPC970_LSU:
35588d211f82304e53694ece666d4a2507b170e4582Chris Lattner  case PPCII::PPC970_FPU:
35688d211f82304e53694ece666d4a2507b170e4582Chris Lattner  case PPCII::PPC970_VALU:
35788d211f82304e53694ece666d4a2507b170e4582Chris Lattner  case PPCII::PPC970_VPERM:
35888d211f82304e53694ece666d4a2507b170e4582Chris Lattner    // We can only issue a branch as the last instruction in a group.
35988d211f82304e53694ece666d4a2507b170e4582Chris Lattner    if (NumIssued == 4) return Hazard;
36088d211f82304e53694ece666d4a2507b170e4582Chris Lattner    break;
36188d211f82304e53694ece666d4a2507b170e4582Chris Lattner  case PPCII::PPC970_CRU:
36288d211f82304e53694ece666d4a2507b170e4582Chris Lattner    // We can only issue a CR instruction in the first two slots.
36388d211f82304e53694ece666d4a2507b170e4582Chris Lattner    if (NumIssued >= 2) return Hazard;
36488d211f82304e53694ece666d4a2507b170e4582Chris Lattner    break;
36588d211f82304e53694ece666d4a2507b170e4582Chris Lattner  case PPCII::PPC970_BRU:
36688d211f82304e53694ece666d4a2507b170e4582Chris Lattner    break;
367c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  }
3686e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
369c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // Do not allow MTCTR and BCTRL to be in the same dispatch group.
37086765fbe170198e7bb40fd8499d1354f4c786f60Ulrich Weigand  if (HasCTRSet && Opcode == PPC::BCTRL)
371c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    return NoopHazard;
3726e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
373c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // If this is a load following a store, make sure it's not to the same or
374c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // overlapping address.
37564c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  if (isLoad && NumStores && !MI->memoperands_empty()) {
37664c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    MachineMemOperand *MO = *MI->memoperands_begin();
37764c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    if (isLoadOfStoredAddress(MO->getSize(),
37864c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel                              MO->getOffset(), MO->getValue()))
379c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner      return NoopHazard;
380c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  }
3816e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
382c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  return NoHazard;
383c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
384c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
385fc54c552963545a81e4ea38e60460590afb2d5aeDan Gohmanvoid PPCHazardRecognizer970::EmitInstruction(SUnit *SU) {
38664c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  MachineInstr *MI = SU->getInstr();
38764c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel
38864c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  if (MI->isDebugValue())
38964c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    return;
39064c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel
39164c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  unsigned Opcode = MI->getOpcode();
3923faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  bool isFirst, isSingle, isCracked, isLoad, isStore;
3936e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick  PPCII::PPC970_Unit InstrType =
39464c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    GetInstrType(Opcode, isFirst, isSingle, isCracked,
3953faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner                 isLoad, isStore);
3966e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick  if (InstrType == PPCII::PPC970_Pseudo) return;
397c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
398c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // Update structural hazard information.
3990c9b559bfd0b476c2dde787285a1195f3142c423Roman Divacky  if (Opcode == PPC::MTCTR || Opcode == PPC::MTCTR8) HasCTRSet = true;
4006e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
401c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  // Track the address stored to.
40264c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  if (isStore && NumStores < 4 && !MI->memoperands_empty()) {
40364c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    MachineMemOperand *MO = *MI->memoperands_begin();
40464c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    StoreSize[NumStores] = MO->getSize();
40564c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    StoreOffset[NumStores] = MO->getOffset();
40664c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel    StoreValue[NumStores] = MO->getValue();
40788d211f82304e53694ece666d4a2507b170e4582Chris Lattner    ++NumStores;
408c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  }
4096e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
41088d211f82304e53694ece666d4a2507b170e4582Chris Lattner  if (InstrType == PPCII::PPC970_BRU || isSingle)
41188d211f82304e53694ece666d4a2507b170e4582Chris Lattner    NumIssued = 4;  // Terminate a d-group.
412c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  ++NumIssued;
4136e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
4143faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  // If this instruction is cracked into two ops by the decoder, remember that
4153faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  // we issued two pieces.
4163faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner  if (isCracked)
4173faad495bc5c23de4852e7a3a13c25203cabfc3eChris Lattner    ++NumIssued;
4186e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
419c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  if (NumIssued == 5)
420c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    EndDispatchGroup();
421c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
422c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner
423c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattnervoid PPCHazardRecognizer970::AdvanceCycle() {
424c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  assert(NumIssued < 5 && "Illegal dispatch group!");
425c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  ++NumIssued;
426c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner  if (NumIssued == 5)
427c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner    EndDispatchGroup();
428c6644188208d4aee9a9d6c428710ec1f69837944Chris Lattner}
42964c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel
43064c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkelvoid PPCHazardRecognizer970::Reset() {
43164c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  EndDispatchGroup();
43264c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel}
43364c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel
434