summaryrefslogtreecommitdiff
path: root/lib/Target/ARM/ARMBaseInstrInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/ARM/ARMBaseInstrInfo.cpp')
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 77cfcb9e50..c824b8bce9 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -1412,3 +1412,66 @@ ConvertToSetZeroFlag(MachineInstr *MI, MachineInstr *CmpInstr) const {
return false;
}
+
+unsigned
+ARMBaseInstrInfo::getNumMicroOps(const MachineInstr *MI,
+ const InstrItineraryData &ItinData) const {
+ if (ItinData.isEmpty())
+ return 1;
+
+ const TargetInstrDesc &Desc = MI->getDesc();
+ unsigned Class = Desc.getSchedClass();
+ unsigned UOps = ItinData.Itineratries[Class].NumMicroOps;
+ if (UOps)
+ return UOps;
+
+ unsigned Opc = MI->getOpcode();
+ switch (Opc) {
+ default:
+ llvm_unreachable("Unexpected multi-uops instruction!");
+ break;
+ case ARM::VSTMQ:
+ return 2;
+
+ // The number of uOps for load / store multiple are determined by the number
+ // registers.
+ // On Cortex-A8, each odd / even pair of register loads / stores
+ // (e.g. r5 + r6) can be completed on the same cycle. The minimum is
+ // 2. For VFP / NEON load / store multiple, the formula is
+ // (#reg / 2) + (#reg % 2) + 1.
+ // On Cortex-A9, the formula is simply (#reg / 2) + (#reg % 2).
+ case ARM::VLDMD:
+ case ARM::VLDMS:
+ case ARM::VLDMD_UPD:
+ case ARM::VLDMS_UPD:
+ case ARM::VSTMD:
+ case ARM::VSTMS:
+ case ARM::VSTMD_UPD:
+ case ARM::VSTMS_UPD: {
+ unsigned NumRegs = MI->getNumOperands() - Desc.getNumOperands();
+ return (NumRegs / 2) + (NumRegs % 2) + 1;
+ }
+ case ARM::LDM_RET:
+ case ARM::LDM:
+ case ARM::LDM_UPD:
+ case ARM::STM:
+ case ARM::STM_UPD:
+ case ARM::tLDM:
+ case ARM::tLDM_UPD:
+ case ARM::tSTM_UPD:
+ case ARM::tPOP_RET:
+ case ARM::tPOP:
+ case ARM::tPUSH:
+ case ARM::t2LDM_RET:
+ case ARM::t2LDM:
+ case ARM::t2LDM_UPD:
+ case ARM::t2STM:
+ case ARM::t2STM_UPD: {
+ // FIXME: Distinquish between Cortex-A8 / Cortex-A9 and other processor
+ // families.
+ unsigned NumRegs = MI->getNumOperands() - Desc.getNumOperands();
+ UOps = (NumRegs / 2) + (NumRegs % 2);
+ return (UOps > 2) ? UOps : 2;
+ }
+ }
+}