DEBUG(std::cerr << "=== Start of dispatch group\n");
// Pipeline units.
NumFXU = NumLSU = NumFPU = 0;
- HasCR = HasVALU = HasVPERM = false;
+ HasCR = HasSPR = HasVALU = HasVPERM = false;
NumIssued = 0;
// Structural hazard info.
case PPC::BL:
case PPC::BLA:
return BR;
+ case PPC::MCRF:
+ case PPC::MFCR:
+ case PPC::MFOCRF:
+ return CR;
+ case PPC::MFLR:
+ case PPC::MFCTR:
+ case PPC::MTLR:
+ case PPC::MTCTR:
+ return SPR;
case PPC::LFS:
case PPC::LFD:
case PPC::LWZ:
case PPC::STFD:
case PPC::STW:
return LSU_ST;
+ case PPC::DIVW:
+ case PPC::DIVWU:
+ case PPC::DIVD:
+ case PPC::DIVDU:
+ return FXU_FIRST;
case PPC::FADDS:
case PPC::FCTIWZ:
case PPC::FRSP:
switch (InstrType) {
default: assert(0 && "Unknown instruction type!");
- case FXU: if (NumFXU == 2) return Hazard;
+ case FXU:
+ case FXU_FIRST: if (NumFXU == 2) return Hazard;
case LSU_ST:
- case LSU_LD: if (NumLSU == 2) return Hazard;
- case FPU: if (NumFPU == 2) return Hazard;
- case CR: if (HasCR) return Hazard;
- case VALU: if (HasVALU) return Hazard;
- case VPERM: if (HasVPERM) return Hazard;
- case BR: break;
+ case LSU_LD: if (NumLSU == 2) return Hazard;
+ case FPU: if (NumFPU == 2) return Hazard;
+ case CR: if (HasCR) return Hazard;
+ case SPR: if (HasSPR) return Hazard;
+ case VALU: if (HasVALU) return Hazard;
+ case VPERM: if (HasVPERM) return Hazard;
+ case BR: break;
}
-
+
+ // We can only issue a CR or SPR instruction, or an FXU instruction that needs
+ // to lead a dispatch group as the first instruction in the group.
+ if (NumIssued != 0 &&
+ (InstrType == CR || InstrType == SPR || InstrType == FXU_FIRST))
+ return Hazard;
+
// We can only issue a branch as the last instruction in a group.
if (NumIssued == 4 && InstrType != BR)
return Hazard;
switch (InstrType) {
default: assert(0 && "Unknown instruction type!");
- case FXU: ++NumFXU; break;
+ case FXU:
+ case FXU_FIRST: ++NumFXU; break;
case LSU_LD:
- case LSU_ST: ++NumLSU; break;
- case FPU: ++NumFPU; break;
- case CR: HasCR = true; break;
- case VALU: HasVALU = true; break;
- case VPERM: HasVPERM = true; break;
- case BR: NumIssued = 4; return; // ends a d-group.
+ case LSU_ST: ++NumLSU; break;
+ case FPU: ++NumFPU; break;
+ case CR: HasCR = true; break;
+ case SPR: HasSPR = true; break;
+ case VALU: HasVALU = true; break;
+ case VPERM: HasVPERM = true; break;
+ case BR: NumIssued = 4; return; // ends a d-group.
}
++NumIssued;
unsigned NumLSU; // Number of Load/Store instructions
unsigned NumFPU; // Number of Floating Point instructions
bool HasCR; // True if Condition Register instruction issued
+ bool HasSPR; // True if Special-Purpose Register instruction used
bool HasVALU; // True if Vector Arithmetic instruction issued
bool HasVPERM; // True if Vector Permute instruction issued
void EndDispatchGroup();
enum PPC970InstrType {
- FXU, LSU_LD, LSU_ST, FPU, CR, VALU, VPERM, BR, PseudoInst
+ FXU, FXU_FIRST, LSU_LD, LSU_ST, FPU, CR, SPR, VALU, VPERM, BR, PseudoInst
};
/// GetInstrType - Classify the specified powerpc opcode according to its