131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- PPCInstrInfo.cpp - PowerPC Instruction Information ----------------===//
2b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman//
3f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman//                     The LLVM Compiler Infrastructure
4f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman//
8f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman//===----------------------------------------------------------------------===//
9f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman//
10f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman// This file contains the PowerPC implementation of the TargetInstrInfo class.
11f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman//
12f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman//===----------------------------------------------------------------------===//
13f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
1416e71f2f70811c69c56052dd146324fe20e31db5Chris Lattner#include "PPCInstrInfo.h"
15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MCTargetDesc/PPCPredicates.h"
1659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "PPC.h"
17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "PPCHazardRecognizers.h"
18f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson#include "PPCInstrBuilder.h"
197194aaf738a1b89441635340403f1c5b06ae18efBill Wendling#include "PPCMachineFunctionInfo.h"
20b1d26f66658cff3ceb7d44a72fbc8c8e975532f9Chris Lattner#include "PPCTargetMachine.h"
215ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel#include "llvm/ADT/Statistic.h"
22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/STLExtras.h"
237a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen#include "llvm/CodeGen/MachineFrameInfo.h"
245ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel#include "llvm/CodeGen/MachineFunctionPass.h"
25f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman#include "llvm/CodeGen/MachineInstrBuilder.h"
267a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen#include "llvm/CodeGen/MachineMemOperand.h"
27243296690ec78fc918762bd73896b09e26537f47Jakob Stoklund Olesen#include "llvm/CodeGen/MachineRegisterInfo.h"
284d989ac93ce608057fb6b13a4068264ab037ecd5Hal Finkel#include "llvm/CodeGen/PseudoSourceValue.h"
2959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/MC/MCAsmInfo.h"
30880d0f6018b6928bdcad291be60c801238619955Bill Wendling#include "llvm/Support/CommandLine.h"
31dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/ErrorHandling.h"
323e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
33dac237e18209b697a8ba122d0ddd9cad4dfba1f8Torok Edwin#include "llvm/Support/raw_ostream.h"
34f2ccb77ee9d8ab35866dae111fa36929689c7511Misha Brukman
35860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel#define GET_INSTRMAP_INFO
364db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng#define GET_INSTRINFO_CTOR
3722fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng#include "PPCGenInstrInfo.inc"
3822fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng
3982bcd236937b378e56e46bdde9c17a3ea3377068Dan Gohmanusing namespace llvm;
40880d0f6018b6928bdcad291be60c801238619955Bill Wendling
4109fdc7baae1b6905fe18df48e2278e74d4e39ccdHal Finkelstatic cl::
427255d2a8084cb6aa96ea0e5f30acfff76df04ee8Hal Finkelopt<bool> DisableCTRLoopAnal("disable-ppc-ctrloop-analysis", cl::Hidden,
437255d2a8084cb6aa96ea0e5f30acfff76df04ee8Hal Finkel            cl::desc("Disable analysis for CTR loops"));
4409fdc7baae1b6905fe18df48e2278e74d4e39ccdHal Finkel
4587c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkelstatic cl::opt<bool> DisableCmpOpt("disable-ppc-cmp-opt",
464029c3feed5c9a5b0793e3da140ecaabef19e3feHal Finkelcl::desc("Disable compare instruction optimization"), cl::Hidden);
474029c3feed5c9a5b0793e3da140ecaabef19e3feHal Finkel
48b1d26f66658cff3ceb7d44a72fbc8c8e975532f9Chris LattnerPPCInstrInfo::PPCInstrInfo(PPCTargetMachine &tm)
494db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng  : PPCGenInstrInfo(PPC::ADJCALLSTACKDOWN, PPC::ADJCALLSTACKUP),
5080ada583f3b40ffb201e54cd57c42f9518039c9eBill Wendling    TM(tm), RI(*TM.getSubtargetImpl()) {}
51b1d26f66658cff3ceb7d44a72fbc8c8e975532f9Chris Lattner
522da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick/// CreateTargetHazardRecognizer - Return the hazard recognizer to use for
532da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick/// this target when scheduling the DAG.
542da8bc8a5f7705ac131184cd247f48500da0d74eAndrew TrickScheduleHazardRecognizer *PPCInstrInfo::CreateTargetHazardRecognizer(
552da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick  const TargetMachine *TM,
562da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick  const ScheduleDAG *DAG) const {
57c6d08f10bf797cc78068ef30bd0e8812a5bdc9a2Hal Finkel  unsigned Directive = TM->getSubtarget<PPCSubtarget>().getDarwinDirective();
58621b77ade2ff46d1d8594bddee6931b2f4a14706Hal Finkel  if (Directive == PPC::DIR_440 || Directive == PPC::DIR_A2 ||
59621b77ade2ff46d1d8594bddee6931b2f4a14706Hal Finkel      Directive == PPC::DIR_E500mc || Directive == PPC::DIR_E5500) {
60768c65f677af3f05c2e94982043f90a1bfaceda5Hal Finkel    const InstrItineraryData *II = TM->getInstrItineraryData();
615b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel    return new PPCScoreboardHazardRecognizer(II, DAG);
62c6d08f10bf797cc78068ef30bd0e8812a5bdc9a2Hal Finkel  }
6364c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel
64a9fa4fd9736f7d1066223f32fa54efbe86c0fcebJakob Stoklund Olesen  return TargetInstrInfo::CreateTargetHazardRecognizer(TM, DAG);
652da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick}
662da8bc8a5f7705ac131184cd247f48500da0d74eAndrew Trick
6764c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel/// CreateTargetPostRAHazardRecognizer - Return the postRA hazard recognizer
6864c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel/// to use for this target when scheduling the DAG.
6964c34e253563a8ba6b41fbce2bb020632cf65961Hal FinkelScheduleHazardRecognizer *PPCInstrInfo::CreateTargetPostRAHazardRecognizer(
7064c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  const InstrItineraryData *II,
7164c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  const ScheduleDAG *DAG) const {
7264c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  unsigned Directive = TM.getSubtarget<PPCSubtarget>().getDarwinDirective();
7364c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel
7464c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  // Most subtargets use a PPC970 recognizer.
75621b77ade2ff46d1d8594bddee6931b2f4a14706Hal Finkel  if (Directive != PPC::DIR_440 && Directive != PPC::DIR_A2 &&
76621b77ade2ff46d1d8594bddee6931b2f4a14706Hal Finkel      Directive != PPC::DIR_E500mc && Directive != PPC::DIR_E5500) {
77041399aad5a3d93c2dc9d2b70cb9b87d4a987eceBenjamin Kramer    assert(TM.getInstrInfo() && "No InstrInfo?");
7864c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel
7980ada583f3b40ffb201e54cd57c42f9518039c9eBill Wendling    return new PPCHazardRecognizer970(TM);
8064c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel  }
8164c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel
824d989ac93ce608057fb6b13a4068264ab037ecd5Hal Finkel  return new PPCScoreboardHazardRecognizer(II, DAG);
8364c34e253563a8ba6b41fbce2bb020632cf65961Hal Finkel}
847164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen
857164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen// Detect 32 -> 64-bit extensions where we may reuse the low sub-register.
867164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesenbool PPCInstrInfo::isCoalescableExtInstr(const MachineInstr &MI,
877164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen                                         unsigned &SrcReg, unsigned &DstReg,
887164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen                                         unsigned &SubIdx) const {
897164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen  switch (MI.getOpcode()) {
907164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen  default: return false;
917164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen  case PPC::EXTSW:
927164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen  case PPC::EXTSW_32_64:
937164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen    SrcReg = MI.getOperand(1).getReg();
947164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen    DstReg = MI.getOperand(0).getReg();
957164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen    SubIdx = PPC::sub_32;
967164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen    return true;
977164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen  }
987164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen}
997164288c3eb52e20454fc757440f867f04eb13a4Jakob Stoklund Olesen
1006e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trickunsigned PPCInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
1019c09c9ec9dab61450800b42cbf746164aa076b88Chris Lattner                                           int &FrameIndex) const {
102f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel  // Note: This list must be kept consistent with LoadRegFromStackSlot.
103408396014742a05cad1c91949d2226169e3f9d80Chris Lattner  switch (MI->getOpcode()) {
104408396014742a05cad1c91949d2226169e3f9d80Chris Lattner  default: break;
105408396014742a05cad1c91949d2226169e3f9d80Chris Lattner  case PPC::LD:
106408396014742a05cad1c91949d2226169e3f9d80Chris Lattner  case PPC::LWZ:
107408396014742a05cad1c91949d2226169e3f9d80Chris Lattner  case PPC::LFS:
108408396014742a05cad1c91949d2226169e3f9d80Chris Lattner  case PPC::LFD:
109f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel  case PPC::RESTORE_CR:
110f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel  case PPC::LVX:
111f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel  case PPC::RESTORE_VRSAVE:
112f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel    // Check for the operands added by addFrameReference (the immediate is the
113f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel    // offset which defaults to 0).
114d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman    if (MI->getOperand(1).isImm() && !MI->getOperand(1).getImm() &&
115d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman        MI->getOperand(2).isFI()) {
1168aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner      FrameIndex = MI->getOperand(2).getIndex();
117408396014742a05cad1c91949d2226169e3f9d80Chris Lattner      return MI->getOperand(0).getReg();
118408396014742a05cad1c91949d2226169e3f9d80Chris Lattner    }
119408396014742a05cad1c91949d2226169e3f9d80Chris Lattner    break;
120408396014742a05cad1c91949d2226169e3f9d80Chris Lattner  }
121408396014742a05cad1c91949d2226169e3f9d80Chris Lattner  return 0;
1226524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner}
123408396014742a05cad1c91949d2226169e3f9d80Chris Lattner
1246e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trickunsigned PPCInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
1256524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner                                          int &FrameIndex) const {
126f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel  // Note: This list must be kept consistent with StoreRegToStackSlot.
1276524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner  switch (MI->getOpcode()) {
1286524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner  default: break;
1293b478b31e297208ef2c9f74750a8a603eb3726fbNate Begeman  case PPC::STD:
1306524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner  case PPC::STW:
1316524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner  case PPC::STFS:
1326524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner  case PPC::STFD:
133f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel  case PPC::SPILL_CR:
134f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel  case PPC::STVX:
135f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel  case PPC::SPILL_VRSAVE:
136f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel    // Check for the operands added by addFrameReference (the immediate is the
137f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel    // offset which defaults to 0).
138d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman    if (MI->getOperand(1).isImm() && !MI->getOperand(1).getImm() &&
139d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman        MI->getOperand(2).isFI()) {
1408aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner      FrameIndex = MI->getOperand(2).getIndex();
1416524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner      return MI->getOperand(0).getReg();
1426524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner    }
1436524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner    break;
1446524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner  }
1456524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner  return 0;
1466524287c53cf727a8ef33517403fcb1bbd7adff9Chris Lattner}
147408396014742a05cad1c91949d2226169e3f9d80Chris Lattner
148043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner// commuteInstruction - We can commute rlwimi instructions, but only if the
149043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner// rotate amt is zero.  We also have to munge the immediates a bit.
15058dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan ChengMachineInstr *
15158dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan ChengPPCInstrInfo::commuteInstruction(MachineInstr *MI, bool NewMI) const {
1528e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman  MachineFunction &MF = *MI->getParent()->getParent();
1538e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman
154043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner  // Normal instructions can be commuted the obvious way.
155171a8adf3168aee2f739f91c1800e9025892c7b5Hal Finkel  if (MI->getOpcode() != PPC::RLWIMI &&
156171a8adf3168aee2f739f91c1800e9025892c7b5Hal Finkel      MI->getOpcode() != PPC::RLWIMIo)
157a9fa4fd9736f7d1066223f32fa54efbe86c0fcebJakob Stoklund Olesen    return TargetInstrInfo::commuteInstruction(MI, NewMI);
1586e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
159043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner  // Cannot commute if it has a non-zero rotate count.
1609a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner  if (MI->getOperand(3).getImm() != 0)
161043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner    return 0;
1626e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
163043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner  // If we have a zero rotate count, we have:
164043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner  //   M = mask(MB,ME)
165043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner  //   Op0 = (Op1 & ~M) | (Op2 & M)
166043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner  // Change this to:
167043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner  //   M = mask((ME+1)&31, (MB-1)&31)
168043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner  //   Op0 = (Op2 & ~M) | (Op1 & M)
169043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner
170043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner  // Swap op1/op2
171a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng  unsigned Reg0 = MI->getOperand(0).getReg();
172043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner  unsigned Reg1 = MI->getOperand(1).getReg();
173043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner  unsigned Reg2 = MI->getOperand(2).getReg();
1746ce7dc2a97260eea5fba414332796464912b9359Evan Cheng  bool Reg1IsKill = MI->getOperand(1).isKill();
1756ce7dc2a97260eea5fba414332796464912b9359Evan Cheng  bool Reg2IsKill = MI->getOperand(2).isKill();
17658dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng  bool ChangeReg0 = false;
177a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng  // If machine instrs are no longer in two-address forms, update
178a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng  // destination register as well.
179a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng  if (Reg0 == Reg1) {
180a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng    // Must be two address instruction!
181e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    assert(MI->getDesc().getOperandConstraint(0, MCOI::TIED_TO) &&
182a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng           "Expecting a two-address instruction!");
183a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng    Reg2IsKill = false;
18458dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng    ChangeReg0 = true;
18558dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng  }
18658dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng
18758dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng  // Masks.
18858dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng  unsigned MB = MI->getOperand(4).getImm();
18958dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng  unsigned ME = MI->getOperand(5).getImm();
19058dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng
19158dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng  if (NewMI) {
19258dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng    // Create a new instruction.
19358dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng    unsigned Reg0 = ChangeReg0 ? Reg2 : MI->getOperand(0).getReg();
19458dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng    bool Reg0IsDead = MI->getOperand(0).isDead();
195d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling    return BuildMI(MF, MI->getDebugLoc(), MI->getDesc())
196587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling      .addReg(Reg0, RegState::Define | getDeadRegState(Reg0IsDead))
197587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling      .addReg(Reg2, getKillRegState(Reg2IsKill))
198587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling      .addReg(Reg1, getKillRegState(Reg1IsKill))
19958dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng      .addImm((ME+1) & 31)
20058dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng      .addImm((MB-1) & 31);
201a4d16a1f0dcdd1ab2862737105f900e2c577532dEvan Cheng  }
20258dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng
20358dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng  if (ChangeReg0)
20458dcb0e0cd3fa973b5fd005aecab1df6aeea5cd6Evan Cheng    MI->getOperand(0).setReg(Reg2);
205e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  MI->getOperand(2).setReg(Reg1);
206e53f4a055f74bded20d6129b4724ddd17fd199f6Chris Lattner  MI->getOperand(1).setReg(Reg2);
207f73823000e2d5d6e1cf65bdf5a107297e18d35fbChris Lattner  MI->getOperand(2).setIsKill(Reg1IsKill);
208f73823000e2d5d6e1cf65bdf5a107297e18d35fbChris Lattner  MI->getOperand(1).setIsKill(Reg2IsKill);
2096e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
210043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner  // Swap the mask around.
2119a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner  MI->getOperand(4).setImm((ME+1) & 31);
2129a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner  MI->getOperand(5).setImm((MB-1) & 31);
213043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner  return MI;
214043870dd85ea41e8972c304b122070a417c8a4bcChris Lattner}
215bbf1c72d51a77bf54c9c684b90a78e59f0b70b2fChris Lattner
2166e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trickvoid PPCInstrInfo::insertNoop(MachineBasicBlock &MBB,
217bbf1c72d51a77bf54c9c684b90a78e59f0b70b2fChris Lattner                              MachineBasicBlock::iterator MI) const {
218c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner  DebugLoc DL;
219d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling  BuildMI(MBB, MI, DL, get(PPC::NOP));
220bbf1c72d51a77bf54c9c684b90a78e59f0b70b2fChris Lattner}
221c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner
222c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner
223c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner// Branch analysis.
22499f823f94374917174f96a7689955b8463db6816Hal Finkel// Note: If the condition register is set to CTR or CTR8 then this is a
22599f823f94374917174f96a7689955b8463db6816Hal Finkel// BDNZ (imm == 1) or BDZ (imm == 0) branch.
226c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattnerbool PPCInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
227c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner                                 MachineBasicBlock *&FBB,
228dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng                                 SmallVectorImpl<MachineOperand> &Cond,
229dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng                                 bool AllowModify) const {
23099f823f94374917174f96a7689955b8463db6816Hal Finkel  bool isPPC64 = TM.getSubtargetImpl()->isPPC64();
23199f823f94374917174f96a7689955b8463db6816Hal Finkel
232c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  // If the block has no terminators, it just falls into the block after it.
233c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  MachineBasicBlock::iterator I = MBB.end();
23493d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  if (I == MBB.begin())
23593d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen    return false;
23693d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  --I;
23793d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  while (I->isDebugValue()) {
23893d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen    if (I == MBB.begin())
23993d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen      return false;
24093d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen    --I;
24193d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  }
24293d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  if (!isUnpredicatedTerminator(I))
243c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner    return false;
244c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner
245c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  // Get the last instruction in the block.
246c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  MachineInstr *LastInst = I;
2476e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
248c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  // If there is only one terminator instruction, process it.
249bfd2ec4a8ef51ebe982363a7e8d7156fdb3827d8Evan Cheng  if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
250c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner    if (LastInst->getOpcode() == PPC::B) {
25182ae933e55839713ea039e7c6353483b14dc5724Evan Cheng      if (!LastInst->getOperand(0).isMBB())
25282ae933e55839713ea039e7c6353483b14dc5724Evan Cheng        return true;
2538aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner      TBB = LastInst->getOperand(0).getMBB();
254c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner      return false;
255289c2d5f4566d8d7722e3934f4763d3df92886f3Chris Lattner    } else if (LastInst->getOpcode() == PPC::BCC) {
25682ae933e55839713ea039e7c6353483b14dc5724Evan Cheng      if (!LastInst->getOperand(2).isMBB())
25782ae933e55839713ea039e7c6353483b14dc5724Evan Cheng        return true;
258c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner      // Block ends with fall-through condbranch.
2598aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner      TBB = LastInst->getOperand(2).getMBB();
260c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner      Cond.push_back(LastInst->getOperand(0));
261c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner      Cond.push_back(LastInst->getOperand(1));
2627c4fe259f8bfeae542cfef25c1f1e9b1ff25a39bChris Lattner      return false;
26399f823f94374917174f96a7689955b8463db6816Hal Finkel    } else if (LastInst->getOpcode() == PPC::BDNZ8 ||
26499f823f94374917174f96a7689955b8463db6816Hal Finkel               LastInst->getOpcode() == PPC::BDNZ) {
26599f823f94374917174f96a7689955b8463db6816Hal Finkel      if (!LastInst->getOperand(0).isMBB())
26699f823f94374917174f96a7689955b8463db6816Hal Finkel        return true;
2677255d2a8084cb6aa96ea0e5f30acfff76df04ee8Hal Finkel      if (DisableCTRLoopAnal)
26809fdc7baae1b6905fe18df48e2278e74d4e39ccdHal Finkel        return true;
26999f823f94374917174f96a7689955b8463db6816Hal Finkel      TBB = LastInst->getOperand(0).getMBB();
27099f823f94374917174f96a7689955b8463db6816Hal Finkel      Cond.push_back(MachineOperand::CreateImm(1));
27199f823f94374917174f96a7689955b8463db6816Hal Finkel      Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR,
27299f823f94374917174f96a7689955b8463db6816Hal Finkel                                               true));
27399f823f94374917174f96a7689955b8463db6816Hal Finkel      return false;
27499f823f94374917174f96a7689955b8463db6816Hal Finkel    } else if (LastInst->getOpcode() == PPC::BDZ8 ||
27599f823f94374917174f96a7689955b8463db6816Hal Finkel               LastInst->getOpcode() == PPC::BDZ) {
27699f823f94374917174f96a7689955b8463db6816Hal Finkel      if (!LastInst->getOperand(0).isMBB())
27799f823f94374917174f96a7689955b8463db6816Hal Finkel        return true;
2787255d2a8084cb6aa96ea0e5f30acfff76df04ee8Hal Finkel      if (DisableCTRLoopAnal)
27909fdc7baae1b6905fe18df48e2278e74d4e39ccdHal Finkel        return true;
28099f823f94374917174f96a7689955b8463db6816Hal Finkel      TBB = LastInst->getOperand(0).getMBB();
28199f823f94374917174f96a7689955b8463db6816Hal Finkel      Cond.push_back(MachineOperand::CreateImm(0));
28299f823f94374917174f96a7689955b8463db6816Hal Finkel      Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR,
28399f823f94374917174f96a7689955b8463db6816Hal Finkel                                               true));
28499f823f94374917174f96a7689955b8463db6816Hal Finkel      return false;
285c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner    }
28699f823f94374917174f96a7689955b8463db6816Hal Finkel
287c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner    // Otherwise, don't know what this is.
288c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner    return true;
289c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  }
2906e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
291c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  // Get the instruction before it if it's a terminator.
292c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  MachineInstr *SecondLastInst = I;
293c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner
294c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  // If there are three terminators, we don't know what sort of block this is.
295c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  if (SecondLastInst && I != MBB.begin() &&
296bfd2ec4a8ef51ebe982363a7e8d7156fdb3827d8Evan Cheng      isUnpredicatedTerminator(--I))
297c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner    return true;
2986e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
299289c2d5f4566d8d7722e3934f4763d3df92886f3Chris Lattner  // If the block ends with PPC::B and PPC:BCC, handle it.
3006e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick  if (SecondLastInst->getOpcode() == PPC::BCC &&
301c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner      LastInst->getOpcode() == PPC::B) {
30282ae933e55839713ea039e7c6353483b14dc5724Evan Cheng    if (!SecondLastInst->getOperand(2).isMBB() ||
30382ae933e55839713ea039e7c6353483b14dc5724Evan Cheng        !LastInst->getOperand(0).isMBB())
30482ae933e55839713ea039e7c6353483b14dc5724Evan Cheng      return true;
3058aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner    TBB =  SecondLastInst->getOperand(2).getMBB();
306c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner    Cond.push_back(SecondLastInst->getOperand(0));
307c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner    Cond.push_back(SecondLastInst->getOperand(1));
3088aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner    FBB = LastInst->getOperand(0).getMBB();
309c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner    return false;
31099f823f94374917174f96a7689955b8463db6816Hal Finkel  } else if ((SecondLastInst->getOpcode() == PPC::BDNZ8 ||
31199f823f94374917174f96a7689955b8463db6816Hal Finkel              SecondLastInst->getOpcode() == PPC::BDNZ) &&
31299f823f94374917174f96a7689955b8463db6816Hal Finkel      LastInst->getOpcode() == PPC::B) {
31399f823f94374917174f96a7689955b8463db6816Hal Finkel    if (!SecondLastInst->getOperand(0).isMBB() ||
31499f823f94374917174f96a7689955b8463db6816Hal Finkel        !LastInst->getOperand(0).isMBB())
31599f823f94374917174f96a7689955b8463db6816Hal Finkel      return true;
3167255d2a8084cb6aa96ea0e5f30acfff76df04ee8Hal Finkel    if (DisableCTRLoopAnal)
31709fdc7baae1b6905fe18df48e2278e74d4e39ccdHal Finkel      return true;
31899f823f94374917174f96a7689955b8463db6816Hal Finkel    TBB = SecondLastInst->getOperand(0).getMBB();
31999f823f94374917174f96a7689955b8463db6816Hal Finkel    Cond.push_back(MachineOperand::CreateImm(1));
32099f823f94374917174f96a7689955b8463db6816Hal Finkel    Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR,
32199f823f94374917174f96a7689955b8463db6816Hal Finkel                                             true));
32299f823f94374917174f96a7689955b8463db6816Hal Finkel    FBB = LastInst->getOperand(0).getMBB();
32399f823f94374917174f96a7689955b8463db6816Hal Finkel    return false;
32499f823f94374917174f96a7689955b8463db6816Hal Finkel  } else if ((SecondLastInst->getOpcode() == PPC::BDZ8 ||
32599f823f94374917174f96a7689955b8463db6816Hal Finkel              SecondLastInst->getOpcode() == PPC::BDZ) &&
32699f823f94374917174f96a7689955b8463db6816Hal Finkel      LastInst->getOpcode() == PPC::B) {
32799f823f94374917174f96a7689955b8463db6816Hal Finkel    if (!SecondLastInst->getOperand(0).isMBB() ||
32899f823f94374917174f96a7689955b8463db6816Hal Finkel        !LastInst->getOperand(0).isMBB())
32999f823f94374917174f96a7689955b8463db6816Hal Finkel      return true;
3307255d2a8084cb6aa96ea0e5f30acfff76df04ee8Hal Finkel    if (DisableCTRLoopAnal)
33109fdc7baae1b6905fe18df48e2278e74d4e39ccdHal Finkel      return true;
33299f823f94374917174f96a7689955b8463db6816Hal Finkel    TBB = SecondLastInst->getOperand(0).getMBB();
33399f823f94374917174f96a7689955b8463db6816Hal Finkel    Cond.push_back(MachineOperand::CreateImm(0));
33499f823f94374917174f96a7689955b8463db6816Hal Finkel    Cond.push_back(MachineOperand::CreateReg(isPPC64 ? PPC::CTR8 : PPC::CTR,
33599f823f94374917174f96a7689955b8463db6816Hal Finkel                                             true));
33699f823f94374917174f96a7689955b8463db6816Hal Finkel    FBB = LastInst->getOperand(0).getMBB();
33799f823f94374917174f96a7689955b8463db6816Hal Finkel    return false;
338c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  }
3396e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
34013e8b51e3ec014c5d7ae83afdf3b8fd29c3a461dDale Johannesen  // If the block ends with two PPC:Bs, handle it.  The second one is not
34113e8b51e3ec014c5d7ae83afdf3b8fd29c3a461dDale Johannesen  // executed, so remove it.
3426e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick  if (SecondLastInst->getOpcode() == PPC::B &&
34313e8b51e3ec014c5d7ae83afdf3b8fd29c3a461dDale Johannesen      LastInst->getOpcode() == PPC::B) {
34482ae933e55839713ea039e7c6353483b14dc5724Evan Cheng    if (!SecondLastInst->getOperand(0).isMBB())
34582ae933e55839713ea039e7c6353483b14dc5724Evan Cheng      return true;
3468aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner    TBB = SecondLastInst->getOperand(0).getMBB();
34713e8b51e3ec014c5d7ae83afdf3b8fd29c3a461dDale Johannesen    I = LastInst;
348dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng    if (AllowModify)
349dc54d317e7a381ef8e4aca80d54ad1466bb85ddaEvan Cheng      I->eraseFromParent();
35013e8b51e3ec014c5d7ae83afdf3b8fd29c3a461dDale Johannesen    return false;
35113e8b51e3ec014c5d7ae83afdf3b8fd29c3a461dDale Johannesen  }
35213e8b51e3ec014c5d7ae83afdf3b8fd29c3a461dDale Johannesen
353c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  // Otherwise, can't handle this.
354c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  return true;
355c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner}
356c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner
357b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Chengunsigned PPCInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
358c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  MachineBasicBlock::iterator I = MBB.end();
359b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Cheng  if (I == MBB.begin()) return 0;
360c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  --I;
36193d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  while (I->isDebugValue()) {
36293d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen    if (I == MBB.begin())
36393d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen      return 0;
36493d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen    --I;
36593d6a7e9c21204c52d6efec6c672163e7de79660Dale Johannesen  }
36699f823f94374917174f96a7689955b8463db6816Hal Finkel  if (I->getOpcode() != PPC::B && I->getOpcode() != PPC::BCC &&
36799f823f94374917174f96a7689955b8463db6816Hal Finkel      I->getOpcode() != PPC::BDNZ8 && I->getOpcode() != PPC::BDNZ &&
36899f823f94374917174f96a7689955b8463db6816Hal Finkel      I->getOpcode() != PPC::BDZ8  && I->getOpcode() != PPC::BDZ)
369b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Cheng    return 0;
3706e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
371c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  // Remove the branch.
372c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  I->eraseFromParent();
3736e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
374c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  I = MBB.end();
375c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner
376b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Cheng  if (I == MBB.begin()) return 1;
377c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  --I;
37899f823f94374917174f96a7689955b8463db6816Hal Finkel  if (I->getOpcode() != PPC::BCC &&
37999f823f94374917174f96a7689955b8463db6816Hal Finkel      I->getOpcode() != PPC::BDNZ8 && I->getOpcode() != PPC::BDNZ &&
38099f823f94374917174f96a7689955b8463db6816Hal Finkel      I->getOpcode() != PPC::BDZ8  && I->getOpcode() != PPC::BDZ)
381b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Cheng    return 1;
3826e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
383c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  // Remove the branch.
384c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner  I->eraseFromParent();
385b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Cheng  return 2;
386c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner}
387c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner
388b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Chengunsigned
389b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan ChengPPCInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
390b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Cheng                           MachineBasicBlock *FBB,
3913bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings                           const SmallVectorImpl<MachineOperand> &Cond,
3923bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings                           DebugLoc DL) const {
3932dc7723474c54efcbcac6265dad0a7271902f1a5Chris Lattner  // Shouldn't be a fall through.
3942dc7723474c54efcbcac6265dad0a7271902f1a5Chris Lattner  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
3956e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick  assert((Cond.size() == 2 || Cond.size() == 0) &&
39654108068b71a7dbc48f4ebf1b2d7d87ca541070aChris Lattner         "PPC branch conditions have two components!");
3976e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
39899f823f94374917174f96a7689955b8463db6816Hal Finkel  bool isPPC64 = TM.getSubtargetImpl()->isPPC64();
39999f823f94374917174f96a7689955b8463db6816Hal Finkel
40054108068b71a7dbc48f4ebf1b2d7d87ca541070aChris Lattner  // One-way branch.
4012dc7723474c54efcbcac6265dad0a7271902f1a5Chris Lattner  if (FBB == 0) {
40254108068b71a7dbc48f4ebf1b2d7d87ca541070aChris Lattner    if (Cond.empty())   // Unconditional branch
4033bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings      BuildMI(&MBB, DL, get(PPC::B)).addMBB(TBB);
40499f823f94374917174f96a7689955b8463db6816Hal Finkel    else if (Cond[1].getReg() == PPC::CTR || Cond[1].getReg() == PPC::CTR8)
40599f823f94374917174f96a7689955b8463db6816Hal Finkel      BuildMI(&MBB, DL, get(Cond[0].getImm() ?
40699f823f94374917174f96a7689955b8463db6816Hal Finkel                              (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
40799f823f94374917174f96a7689955b8463db6816Hal Finkel                              (isPPC64 ? PPC::BDZ8  : PPC::BDZ))).addMBB(TBB);
40854108068b71a7dbc48f4ebf1b2d7d87ca541070aChris Lattner    else                // Conditional branch
4093bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings      BuildMI(&MBB, DL, get(PPC::BCC))
41018258c640466274c26e89016e361ec411ff78520Chris Lattner        .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
411b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Cheng    return 1;
4122dc7723474c54efcbcac6265dad0a7271902f1a5Chris Lattner  }
4136e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
414879d09cf130f3760a08865913c04d9ff328fad5fChris Lattner  // Two-way Conditional Branch.
41599f823f94374917174f96a7689955b8463db6816Hal Finkel  if (Cond[1].getReg() == PPC::CTR || Cond[1].getReg() == PPC::CTR8)
41699f823f94374917174f96a7689955b8463db6816Hal Finkel    BuildMI(&MBB, DL, get(Cond[0].getImm() ?
41799f823f94374917174f96a7689955b8463db6816Hal Finkel                            (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
41899f823f94374917174f96a7689955b8463db6816Hal Finkel                            (isPPC64 ? PPC::BDZ8  : PPC::BDZ))).addMBB(TBB);
41999f823f94374917174f96a7689955b8463db6816Hal Finkel  else
42099f823f94374917174f96a7689955b8463db6816Hal Finkel    BuildMI(&MBB, DL, get(PPC::BCC))
42199f823f94374917174f96a7689955b8463db6816Hal Finkel      .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
4223bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings  BuildMI(&MBB, DL, get(PPC::B)).addMBB(FBB);
423b5cdaa257e167a08a8a54ea9249d847ccc415ce0Evan Cheng  return 2;
424c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner}
425c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner
426ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel// Select analysis.
427ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkelbool PPCInstrInfo::canInsertSelect(const MachineBasicBlock &MBB,
428ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel                const SmallVectorImpl<MachineOperand> &Cond,
429ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel                unsigned TrueReg, unsigned FalseReg,
430ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel                int &CondCycles, int &TrueCycles, int &FalseCycles) const {
431ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  if (!TM.getSubtargetImpl()->hasISEL())
432ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel    return false;
433ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel
434ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  if (Cond.size() != 2)
435ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel    return false;
436ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel
437ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  // If this is really a bdnz-like condition, then it cannot be turned into a
438ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  // select.
439ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  if (Cond[1].getReg() == PPC::CTR || Cond[1].getReg() == PPC::CTR8)
440ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel    return false;
441ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel
442ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  // Check register classes.
443ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
444ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  const TargetRegisterClass *RC =
445ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel    RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
446ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  if (!RC)
447ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel    return false;
448ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel
449ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  // isel is for regular integer GPRs only.
450ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  if (!PPC::GPRCRegClass.hasSubClassEq(RC) &&
451ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel      !PPC::GPRC_NOR0RegClass.hasSubClassEq(RC) &&
452ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel      !PPC::G8RCRegClass.hasSubClassEq(RC) &&
453ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel      !PPC::G8RC_NOX0RegClass.hasSubClassEq(RC))
454ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel    return false;
455ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel
456ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  // FIXME: These numbers are for the A2, how well they work for other cores is
457ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  // an open question. On the A2, the isel instruction has a 2-cycle latency
458ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  // but single-cycle throughput. These numbers are used in combination with
459ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  // the MispredictPenalty setting from the active SchedMachineModel.
460ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  CondCycles = 1;
461ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  TrueCycles = 1;
462ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  FalseCycles = 1;
463ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel
464ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  return true;
465ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel}
466ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel
467ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkelvoid PPCInstrInfo::insertSelect(MachineBasicBlock &MBB,
468ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel                                MachineBasicBlock::iterator MI, DebugLoc dl,
469ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel                                unsigned DestReg,
470ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel                                const SmallVectorImpl<MachineOperand> &Cond,
471ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel                                unsigned TrueReg, unsigned FalseReg) const {
472ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  assert(Cond.size() == 2 &&
473ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel         "PPC branch conditions have two components!");
474ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel
475ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  assert(TM.getSubtargetImpl()->hasISEL() &&
476ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel         "Cannot insert select on target without ISEL support");
477ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel
478ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  // Get the register classes.
479ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
480ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  const TargetRegisterClass *RC =
481ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel    RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));
482ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  assert(RC && "TrueReg and FalseReg must have overlapping register classes");
483ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel
484ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel  bool Is64Bit = PPC::G8RCRegClass.hasSubClassEq(RC) ||
485ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel                 PPC::G8RC_NOX0RegClass.hasSubClassEq(RC);
486ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel  assert((Is64Bit ||
487ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel          PPC::GPRCRegClass.hasSubClassEq(RC) ||
488ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel          PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) &&
489ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel         "isel is for regular integer GPRs only");
490ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel
491ae4f3f6820c28a4ba4fab538f5ff4724cbe82d50Hal Finkel  unsigned OpCode = Is64Bit ? PPC::ISEL8 : PPC::ISEL;
492ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  unsigned SelectPred = Cond[0].getImm();
493ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel
494ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  unsigned SubIdx;
495ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  bool SwapOps;
496ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  switch (SelectPred) {
497ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  default: llvm_unreachable("invalid predicate for isel");
498ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  case PPC::PRED_EQ: SubIdx = PPC::sub_eq; SwapOps = false; break;
499ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  case PPC::PRED_NE: SubIdx = PPC::sub_eq; SwapOps = true; break;
500ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  case PPC::PRED_LT: SubIdx = PPC::sub_lt; SwapOps = false; break;
501ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  case PPC::PRED_GE: SubIdx = PPC::sub_lt; SwapOps = true; break;
502ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  case PPC::PRED_GT: SubIdx = PPC::sub_gt; SwapOps = false; break;
503ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  case PPC::PRED_LE: SubIdx = PPC::sub_gt; SwapOps = true; break;
504ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  case PPC::PRED_UN: SubIdx = PPC::sub_un; SwapOps = false; break;
505ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  case PPC::PRED_NU: SubIdx = PPC::sub_un; SwapOps = true; break;
506ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  }
507ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel
508ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  unsigned FirstReg =  SwapOps ? FalseReg : TrueReg,
509ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel           SecondReg = SwapOps ? TrueReg  : FalseReg;
510ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel
511ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  // The first input register of isel cannot be r0. If it is a member
512ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  // of a register class that can be r0, then copy it first (the
513ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  // register allocator should eliminate the copy).
514ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  if (MRI.getRegClass(FirstReg)->contains(PPC::R0) ||
515ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel      MRI.getRegClass(FirstReg)->contains(PPC::X0)) {
516ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel    const TargetRegisterClass *FirstRC =
517ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel      MRI.getRegClass(FirstReg)->contains(PPC::X0) ?
518ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel        &PPC::G8RC_NOX0RegClass : &PPC::GPRC_NOR0RegClass;
519ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel    unsigned OldFirstReg = FirstReg;
520ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel    FirstReg = MRI.createVirtualRegister(FirstRC);
521ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel    BuildMI(MBB, MI, dl, get(TargetOpcode::COPY), FirstReg)
522ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel      .addReg(OldFirstReg);
523ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  }
524ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel
525ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel  BuildMI(MBB, MI, dl, get(OpCode), DestReg)
526ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel    .addReg(FirstReg).addReg(SecondReg)
527ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel    .addReg(Cond[1].getReg(), 0, SubIdx);
528ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel}
529ff56d1a2011f239e114267c13302ea26db4f8046Hal Finkel
53027689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesenvoid PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
53127689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen                               MachineBasicBlock::iterator I, DebugLoc DL,
53227689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen                               unsigned DestReg, unsigned SrcReg,
53327689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen                               bool KillSrc) const {
53427689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen  unsigned Opc;
53527689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen  if (PPC::GPRCRegClass.contains(DestReg, SrcReg))
53627689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen    Opc = PPC::OR;
53727689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen  else if (PPC::G8RCRegClass.contains(DestReg, SrcReg))
53827689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen    Opc = PPC::OR8;
53927689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen  else if (PPC::F4RCRegClass.contains(DestReg, SrcReg))
54027689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen    Opc = PPC::FMR;
54127689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen  else if (PPC::CRRCRegClass.contains(DestReg, SrcReg))
54227689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen    Opc = PPC::MCRF;
54327689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen  else if (PPC::VRRCRegClass.contains(DestReg, SrcReg))
54427689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen    Opc = PPC::VOR;
54527689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen  else if (PPC::CRBITRCRegClass.contains(DestReg, SrcReg))
54627689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen    Opc = PPC::CROR;
54727689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen  else
54827689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen    llvm_unreachable("Impossible reg-to-reg copy");
549d10fd9791c20fd8368fa0ce94b626b769c6c8ba0Owen Anderson
550e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  const MCInstrDesc &MCID = get(Opc);
551e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng  if (MCID.getNumOperands() == 3)
552e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    BuildMI(MBB, I, DL, MCID, DestReg)
55327689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen      .addReg(SrcReg).addReg(SrcReg, getKillRegState(KillSrc));
55427689b0affee8fb1bfbef11dcc84287b7757cfe8Jakob Stoklund Olesen  else
555e837dead3c8dc3445ef6a0e2322179c57e264a13Evan Cheng    BuildMI(MBB, I, DL, MCID, DestReg).addReg(SrcReg, getKillRegState(KillSrc));
556d10fd9791c20fd8368fa0ce94b626b769c6c8ba0Owen Anderson}
557d10fd9791c20fd8368fa0ce94b626b769c6c8ba0Owen Anderson
5583fd0018af1b692cabfa5a002bf41f1e756aa9ddeHal Finkel// This function returns true if a CR spill is necessary and false otherwise.
5594a66e9a57e679b4f3243bf2061daf53c70102030Bill Wendlingbool
5608e5f2c6f65841542e2a7092553fe42a00048e4c7Dan GohmanPPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF,
5618e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman                                  unsigned SrcReg, bool isKill,
5624a66e9a57e679b4f3243bf2061daf53c70102030Bill Wendling                                  int FrameIdx,
5634a66e9a57e679b4f3243bf2061daf53c70102030Bill Wendling                                  const TargetRegisterClass *RC,
564324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel                                  SmallVectorImpl<MachineInstr*> &NewMIs,
5653f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel                                  bool &NonRI, bool &SpillsVRS) const{
566f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel  // Note: If additional store instructions are added here,
567f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel  // update isStoreToStackSlot.
568f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel
569c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner  DebugLoc DL;
570c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper  if (PPC::GPRCRegClass.hasSubClassEq(RC)) {
5717257fda1b3b047f6fd46df8a9999580fcfafbfaeHal Finkel    NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STW))
5727257fda1b3b047f6fd46df8a9999580fcfafbfaeHal Finkel                                       .addReg(SrcReg,
5737257fda1b3b047f6fd46df8a9999580fcfafbfaeHal Finkel                                               getKillRegState(isKill)),
5747257fda1b3b047f6fd46df8a9999580fcfafbfaeHal Finkel                                       FrameIdx));
575c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper  } else if (PPC::G8RCRegClass.hasSubClassEq(RC)) {
5767257fda1b3b047f6fd46df8a9999580fcfafbfaeHal Finkel    NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STD))
5777257fda1b3b047f6fd46df8a9999580fcfafbfaeHal Finkel                                       .addReg(SrcReg,
5787257fda1b3b047f6fd46df8a9999580fcfafbfaeHal Finkel                                               getKillRegState(isKill)),
5797257fda1b3b047f6fd46df8a9999580fcfafbfaeHal Finkel                                       FrameIdx));
580c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper  } else if (PPC::F8RCRegClass.hasSubClassEq(RC)) {
58121b5541814d57d0a31f353948e4e933dbb1af6a4Dale Johannesen    NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STFD))
582587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling                                       .addReg(SrcReg,
583587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling                                               getKillRegState(isKill)),
584587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling                                       FrameIdx));
585c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper  } else if (PPC::F4RCRegClass.hasSubClassEq(RC)) {
58621b5541814d57d0a31f353948e4e933dbb1af6a4Dale Johannesen    NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STFS))
587587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling                                       .addReg(SrcReg,
588587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling                                               getKillRegState(isKill)),
589587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling                                       FrameIdx));
590c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper  } else if (PPC::CRRCRegClass.hasSubClassEq(RC)) {
5917285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel    NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::SPILL_CR))
5927285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel                                       .addReg(SrcReg,
5937285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel                                               getKillRegState(isKill)),
5947285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel                                       FrameIdx));
5957285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel    return true;
596c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper  } else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) {
5970404cd97e4f6ebfe4f8057d4e21119d77654dff2Nicolas Geoffray    // FIXME: We use CRi here because there is no mtcrf on a bit. Since the
5980404cd97e4f6ebfe4f8057d4e21119d77654dff2Nicolas Geoffray    // backend currently only uses CR1EQ as an individual bit, this should
5990404cd97e4f6ebfe4f8057d4e21119d77654dff2Nicolas Geoffray    // not cause any bug. If we need other uses of CR bits, the following
6000404cd97e4f6ebfe4f8057d4e21119d77654dff2Nicolas Geoffray    // code may be invalid.
6019348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray    unsigned Reg = 0;
6026a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller    if (SrcReg == PPC::CR0LT || SrcReg == PPC::CR0GT ||
6036a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller        SrcReg == PPC::CR0EQ || SrcReg == PPC::CR0UN)
6049348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray      Reg = PPC::CR0;
6056a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller    else if (SrcReg == PPC::CR1LT || SrcReg == PPC::CR1GT ||
6066a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller             SrcReg == PPC::CR1EQ || SrcReg == PPC::CR1UN)
6079348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray      Reg = PPC::CR1;
6086a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller    else if (SrcReg == PPC::CR2LT || SrcReg == PPC::CR2GT ||
6096a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller             SrcReg == PPC::CR2EQ || SrcReg == PPC::CR2UN)
6109348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray      Reg = PPC::CR2;
6116a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller    else if (SrcReg == PPC::CR3LT || SrcReg == PPC::CR3GT ||
6126a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller             SrcReg == PPC::CR3EQ || SrcReg == PPC::CR3UN)
6139348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray      Reg = PPC::CR3;
6146a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller    else if (SrcReg == PPC::CR4LT || SrcReg == PPC::CR4GT ||
6156a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller             SrcReg == PPC::CR4EQ || SrcReg == PPC::CR4UN)
6169348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray      Reg = PPC::CR4;
6176a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller    else if (SrcReg == PPC::CR5LT || SrcReg == PPC::CR5GT ||
6186a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller             SrcReg == PPC::CR5EQ || SrcReg == PPC::CR5UN)
6199348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray      Reg = PPC::CR5;
6206a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller    else if (SrcReg == PPC::CR6LT || SrcReg == PPC::CR6GT ||
6216a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller             SrcReg == PPC::CR6EQ || SrcReg == PPC::CR6UN)
6229348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray      Reg = PPC::CR6;
6236a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller    else if (SrcReg == PPC::CR7LT || SrcReg == PPC::CR7GT ||
6246a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller             SrcReg == PPC::CR7EQ || SrcReg == PPC::CR7UN)
6259348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray      Reg = PPC::CR7;
6269348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray
6276e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick    return StoreRegToStackSlot(MF, Reg, isKill, FrameIdx,
6283f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel                               &PPC::CRRCRegClass, NewMIs, NonRI, SpillsVRS);
6299348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray
630c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper  } else if (PPC::VRRCRegClass.hasSubClassEq(RC)) {
631324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel    NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STVX))
632324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel                                       .addReg(SrcReg,
633324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel                                               getKillRegState(isKill)),
634324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel                                       FrameIdx));
635324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel    NonRI = true;
63610f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel  } else if (PPC::VRSAVERCRegClass.hasSubClassEq(RC)) {
637b7e11e400dabced046e7ec53a66926716563bb36Hal Finkel    assert(TM.getSubtargetImpl()->isDarwin() &&
638b7e11e400dabced046e7ec53a66926716563bb36Hal Finkel           "VRSAVE only needs spill/restore on Darwin");
63910f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel    NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::SPILL_VRSAVE))
64010f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel                                       .addReg(SrcReg,
64110f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel                                               getKillRegState(isKill)),
64210f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel                                       FrameIdx));
6433f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel    SpillsVRS = true;
644f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  } else {
645c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unknown regclass!");
646f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  }
6477194aaf738a1b89441635340403f1c5b06ae18efBill Wendling
6487194aaf738a1b89441635340403f1c5b06ae18efBill Wendling  return false;
649f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson}
650f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson
651f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Andersonvoid
652f6372aa1cc568df19da7c5023e83c75aa9404a07Owen AndersonPPCInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
6537194aaf738a1b89441635340403f1c5b06ae18efBill Wendling                                  MachineBasicBlock::iterator MI,
6547194aaf738a1b89441635340403f1c5b06ae18efBill Wendling                                  unsigned SrcReg, bool isKill, int FrameIdx,
655746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                                  const TargetRegisterClass *RC,
656746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                                  const TargetRegisterInfo *TRI) const {
6578e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman  MachineFunction &MF = *MBB.getParent();
658f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  SmallVector<MachineInstr*, 4> NewMIs;
6597194aaf738a1b89441635340403f1c5b06ae18efBill Wendling
6600cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel  PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
6610cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel  FuncInfo->setHasSpills();
6620cfb42adb5072fb19a01dba3ea58a33fd5927947Hal Finkel
6633f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel  bool NonRI = false, SpillsVRS = false;
6643f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel  if (StoreRegToStackSlot(MF, SrcReg, isKill, FrameIdx, RC, NewMIs,
6653f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel                          NonRI, SpillsVRS))
6667194aaf738a1b89441635340403f1c5b06ae18efBill Wendling    FuncInfo->setSpillsCR();
6677194aaf738a1b89441635340403f1c5b06ae18efBill Wendling
6683f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel  if (SpillsVRS)
6693f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel    FuncInfo->setSpillsVRSAVE();
6703f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel
671324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel  if (NonRI)
672324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel    FuncInfo->setHasNonRISpills();
673324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel
674f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  for (unsigned i = 0, e = NewMIs.size(); i != e; ++i)
675f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson    MBB.insert(MI, NewMIs[i]);
6767a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen
6777a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen  const MachineFrameInfo &MFI = *MF.getFrameInfo();
6787a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen  MachineMemOperand *MMO =
679978e0dfe46e481bfb1281e683aa308329e879e95Jay Foad    MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx),
68059db5496f4fc2ef6111569e542f8b65480ef14c1Chris Lattner                            MachineMemOperand::MOStore,
6817a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen                            MFI.getObjectSize(FrameIdx),
6827a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen                            MFI.getObjectAlignment(FrameIdx));
6837a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen  NewMIs.back()->addMemOperand(MF, MMO);
684f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson}
685f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson
686d21e930eac3d99dd77ee33ea5826700b4bc97ae8Hal Finkelbool
687d1c321a89ab999b9bb602b0f398ecd4c2022262cBill WendlingPPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL,
6888e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman                                   unsigned DestReg, int FrameIdx,
6894a66e9a57e679b4f3243bf2061daf53c70102030Bill Wendling                                   const TargetRegisterClass *RC,
690324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel                                   SmallVectorImpl<MachineInstr*> &NewMIs,
6913f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel                                   bool &NonRI, bool &SpillsVRS) const{
692f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel  // Note: If additional load instructions are added here,
693f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel  // update isLoadFromStackSlot.
694f25f93b685a6cb91d8370ae5dc1436a863a670d2Hal Finkel
695c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper  if (PPC::GPRCRegClass.hasSubClassEq(RC)) {
696fc8058696820332cfd3d382f6534edc96420a0b1Hal Finkel    NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ),
697fc8058696820332cfd3d382f6534edc96420a0b1Hal Finkel                                               DestReg), FrameIdx));
698c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper  } else if (PPC::G8RCRegClass.hasSubClassEq(RC)) {
699fc8058696820332cfd3d382f6534edc96420a0b1Hal Finkel    NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LD), DestReg),
700fc8058696820332cfd3d382f6534edc96420a0b1Hal Finkel                                       FrameIdx));
701c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper  } else if (PPC::F8RCRegClass.hasSubClassEq(RC)) {
702d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling    NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LFD), DestReg),
703f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson                                       FrameIdx));
704c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper  } else if (PPC::F4RCRegClass.hasSubClassEq(RC)) {
705d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling    NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LFS), DestReg),
706f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson                                       FrameIdx));
707c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper  } else if (PPC::CRRCRegClass.hasSubClassEq(RC)) {
7087285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel    NewMIs.push_back(addFrameReference(BuildMI(MF, DL,
7097285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel                                               get(PPC::RESTORE_CR), DestReg),
7107285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel                                       FrameIdx));
7117285e8d98c9a44b7efe792462188cfe713dd9641Hal Finkel    return true;
712c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper  } else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) {
7136e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick
7149348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray    unsigned Reg = 0;
7156a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller    if (DestReg == PPC::CR0LT || DestReg == PPC::CR0GT ||
7166a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller        DestReg == PPC::CR0EQ || DestReg == PPC::CR0UN)
7179348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray      Reg = PPC::CR0;
7186a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller    else if (DestReg == PPC::CR1LT || DestReg == PPC::CR1GT ||
7196a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller             DestReg == PPC::CR1EQ || DestReg == PPC::CR1UN)
7209348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray      Reg = PPC::CR1;
7216a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller    else if (DestReg == PPC::CR2LT || DestReg == PPC::CR2GT ||
7226a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller             DestReg == PPC::CR2EQ || DestReg == PPC::CR2UN)
7239348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray      Reg = PPC::CR2;
7246a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller    else if (DestReg == PPC::CR3LT || DestReg == PPC::CR3GT ||
7256a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller             DestReg == PPC::CR3EQ || DestReg == PPC::CR3UN)
7269348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray      Reg = PPC::CR3;
7276a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller    else if (DestReg == PPC::CR4LT || DestReg == PPC::CR4GT ||
7286a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller             DestReg == PPC::CR4EQ || DestReg == PPC::CR4UN)
7299348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray      Reg = PPC::CR4;
7306a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller    else if (DestReg == PPC::CR5LT || DestReg == PPC::CR5GT ||
7316a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller             DestReg == PPC::CR5EQ || DestReg == PPC::CR5UN)
7329348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray      Reg = PPC::CR5;
7336a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller    else if (DestReg == PPC::CR6LT || DestReg == PPC::CR6GT ||
7346a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller             DestReg == PPC::CR6EQ || DestReg == PPC::CR6UN)
7359348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray      Reg = PPC::CR6;
7366a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller    else if (DestReg == PPC::CR7LT || DestReg == PPC::CR7GT ||
7376a3a1ba97e996bfdc061f9a51bd4cf4915962913Tilmann Scheller             DestReg == PPC::CR7EQ || DestReg == PPC::CR7UN)
7389348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray      Reg = PPC::CR7;
7399348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray
7406e8f4c404825b79f9b9176483653f1aa927dfbdeAndrew Trick    return LoadRegFromStackSlot(MF, DL, Reg, FrameIdx,
7413f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel                                &PPC::CRRCRegClass, NewMIs, NonRI, SpillsVRS);
7429348c69dcfe1aa1e7f92752a18222dcfbcd96214Nicolas Geoffray
743c909950c384e8234a7b3c5a76b7f79e3f7012cebCraig Topper  } else if (PPC::VRRCRegClass.hasSubClassEq(RC)) {
744324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel    NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LVX), DestReg),
745324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel                                       FrameIdx));
746324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel    NonRI = true;
74710f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel  } else if (PPC::VRSAVERCRegClass.hasSubClassEq(RC)) {
748b7e11e400dabced046e7ec53a66926716563bb36Hal Finkel    assert(TM.getSubtargetImpl()->isDarwin() &&
749b7e11e400dabced046e7ec53a66926716563bb36Hal Finkel           "VRSAVE only needs spill/restore on Darwin");
75010f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel    NewMIs.push_back(addFrameReference(BuildMI(MF, DL,
75110f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel                                               get(PPC::RESTORE_VRSAVE),
75210f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel                                               DestReg),
75310f7f2a222d0e83dc0c33ad506a7686190c2f7a2Hal Finkel                                       FrameIdx));
7543f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel    SpillsVRS = true;
755f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  } else {
756c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Unknown regclass!");
757f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  }
758d21e930eac3d99dd77ee33ea5826700b4bc97ae8Hal Finkel
759d21e930eac3d99dd77ee33ea5826700b4bc97ae8Hal Finkel  return false;
760f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson}
761f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson
762f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Andersonvoid
763f6372aa1cc568df19da7c5023e83c75aa9404a07Owen AndersonPPCInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
7647194aaf738a1b89441635340403f1c5b06ae18efBill Wendling                                   MachineBasicBlock::iterator MI,
7657194aaf738a1b89441635340403f1c5b06ae18efBill Wendling                                   unsigned DestReg, int FrameIdx,
766746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                                   const TargetRegisterClass *RC,
767746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                                   const TargetRegisterInfo *TRI) const {
7688e5f2c6f65841542e2a7092553fe42a00048e4c7Dan Gohman  MachineFunction &MF = *MBB.getParent();
769f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  SmallVector<MachineInstr*, 4> NewMIs;
770c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner  DebugLoc DL;
771d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling  if (MI != MBB.end()) DL = MI->getDebugLoc();
772324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel
773324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel  PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>();
774324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel  FuncInfo->setHasSpills();
775324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel
7763f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel  bool NonRI = false, SpillsVRS = false;
7773f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel  if (LoadRegFromStackSlot(MF, DL, DestReg, FrameIdx, RC, NewMIs,
7783f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel                           NonRI, SpillsVRS))
779d21e930eac3d99dd77ee33ea5826700b4bc97ae8Hal Finkel    FuncInfo->setSpillsCR();
780324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel
7813f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel  if (SpillsVRS)
7823f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel    FuncInfo->setSpillsVRSAVE();
7833f2c047f32c9b488d9c49bb2dc87b979530dab3fHal Finkel
784324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel  if (NonRI)
785324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel    FuncInfo->setHasNonRISpills();
786324972904353594ad4a0cdfc79370f85e9fb9c8fHal Finkel
787f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  for (unsigned i = 0, e = NewMIs.size(); i != e; ++i)
788f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson    MBB.insert(MI, NewMIs[i]);
7897a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen
7907a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen  const MachineFrameInfo &MFI = *MF.getFrameInfo();
7917a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen  MachineMemOperand *MMO =
792978e0dfe46e481bfb1281e683aa308329e879e95Jay Foad    MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx),
79359db5496f4fc2ef6111569e542f8b65480ef14c1Chris Lattner                            MachineMemOperand::MOLoad,
7947a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen                            MFI.getObjectSize(FrameIdx),
7957a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen                            MFI.getObjectAlignment(FrameIdx));
7967a79fcb55b83b8b98b9853c390cc5bf8ce382dd3Jakob Stoklund Olesen  NewMIs.back()->addMemOperand(MF, MMO);
797f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson}
798f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson
799c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattnerbool PPCInstrInfo::
80044eb65cf58e3ab9b5621ce72256d1621a18aeed7Owen AndersonReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
8017c4fe259f8bfeae542cfef25c1f1e9b1ff25a39bChris Lattner  assert(Cond.size() == 2 && "Invalid PPC branch opcode!");
80299f823f94374917174f96a7689955b8463db6816Hal Finkel  if (Cond[1].getReg() == PPC::CTR8 || Cond[1].getReg() == PPC::CTR)
80399f823f94374917174f96a7689955b8463db6816Hal Finkel    Cond[0].setImm(Cond[0].getImm() == 0 ? 1 : 0);
80499f823f94374917174f96a7689955b8463db6816Hal Finkel  else
80599f823f94374917174f96a7689955b8463db6816Hal Finkel    // Leave the CR# the same, but invert the condition.
80699f823f94374917174f96a7689955b8463db6816Hal Finkel    Cond[0].setImm(PPC::InvertPredicate((PPC::Predicate)Cond[0].getImm()));
8077c4fe259f8bfeae542cfef25c1f1e9b1ff25a39bChris Lattner  return false;
808c50e2bcdf7bff1f9681ab80e52691f274950fab5Chris Lattner}
80952e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray
810839b9096538f790a2bb060547df24703807cb83bHal Finkelbool PPCInstrInfo::FoldImmediate(MachineInstr *UseMI, MachineInstr *DefMI,
811839b9096538f790a2bb060547df24703807cb83bHal Finkel                             unsigned Reg, MachineRegisterInfo *MRI) const {
812839b9096538f790a2bb060547df24703807cb83bHal Finkel  // For some instructions, it is legal to fold ZERO into the RA register field.
813839b9096538f790a2bb060547df24703807cb83bHal Finkel  // A zero immediate should always be loaded with a single li.
814839b9096538f790a2bb060547df24703807cb83bHal Finkel  unsigned DefOpc = DefMI->getOpcode();
815839b9096538f790a2bb060547df24703807cb83bHal Finkel  if (DefOpc != PPC::LI && DefOpc != PPC::LI8)
816839b9096538f790a2bb060547df24703807cb83bHal Finkel    return false;
817839b9096538f790a2bb060547df24703807cb83bHal Finkel  if (!DefMI->getOperand(1).isImm())
818839b9096538f790a2bb060547df24703807cb83bHal Finkel    return false;
819839b9096538f790a2bb060547df24703807cb83bHal Finkel  if (DefMI->getOperand(1).getImm() != 0)
820839b9096538f790a2bb060547df24703807cb83bHal Finkel    return false;
821839b9096538f790a2bb060547df24703807cb83bHal Finkel
822839b9096538f790a2bb060547df24703807cb83bHal Finkel  // Note that we cannot here invert the arguments of an isel in order to fold
823839b9096538f790a2bb060547df24703807cb83bHal Finkel  // a ZERO into what is presented as the second argument. All we have here
824839b9096538f790a2bb060547df24703807cb83bHal Finkel  // is the condition bit, and that might come from a CR-logical bit operation.
825839b9096538f790a2bb060547df24703807cb83bHal Finkel
826839b9096538f790a2bb060547df24703807cb83bHal Finkel  const MCInstrDesc &UseMCID = UseMI->getDesc();
827839b9096538f790a2bb060547df24703807cb83bHal Finkel
828839b9096538f790a2bb060547df24703807cb83bHal Finkel  // Only fold into real machine instructions.
829839b9096538f790a2bb060547df24703807cb83bHal Finkel  if (UseMCID.isPseudo())
830839b9096538f790a2bb060547df24703807cb83bHal Finkel    return false;
831839b9096538f790a2bb060547df24703807cb83bHal Finkel
832839b9096538f790a2bb060547df24703807cb83bHal Finkel  unsigned UseIdx;
833839b9096538f790a2bb060547df24703807cb83bHal Finkel  for (UseIdx = 0; UseIdx < UseMI->getNumOperands(); ++UseIdx)
834839b9096538f790a2bb060547df24703807cb83bHal Finkel    if (UseMI->getOperand(UseIdx).isReg() &&
835839b9096538f790a2bb060547df24703807cb83bHal Finkel        UseMI->getOperand(UseIdx).getReg() == Reg)
836839b9096538f790a2bb060547df24703807cb83bHal Finkel      break;
837839b9096538f790a2bb060547df24703807cb83bHal Finkel
838839b9096538f790a2bb060547df24703807cb83bHal Finkel  assert(UseIdx < UseMI->getNumOperands() && "Cannot find Reg in UseMI");
839839b9096538f790a2bb060547df24703807cb83bHal Finkel  assert(UseIdx < UseMCID.getNumOperands() && "No operand description for Reg");
840839b9096538f790a2bb060547df24703807cb83bHal Finkel
841839b9096538f790a2bb060547df24703807cb83bHal Finkel  const MCOperandInfo *UseInfo = &UseMCID.OpInfo[UseIdx];
842839b9096538f790a2bb060547df24703807cb83bHal Finkel
843839b9096538f790a2bb060547df24703807cb83bHal Finkel  // We can fold the zero if this register requires a GPRC_NOR0/G8RC_NOX0
844839b9096538f790a2bb060547df24703807cb83bHal Finkel  // register (which might also be specified as a pointer class kind).
845839b9096538f790a2bb060547df24703807cb83bHal Finkel  if (UseInfo->isLookupPtrRegClass()) {
846839b9096538f790a2bb060547df24703807cb83bHal Finkel    if (UseInfo->RegClass /* Kind */ != 1)
847839b9096538f790a2bb060547df24703807cb83bHal Finkel      return false;
848839b9096538f790a2bb060547df24703807cb83bHal Finkel  } else {
849839b9096538f790a2bb060547df24703807cb83bHal Finkel    if (UseInfo->RegClass != PPC::GPRC_NOR0RegClassID &&
850839b9096538f790a2bb060547df24703807cb83bHal Finkel        UseInfo->RegClass != PPC::G8RC_NOX0RegClassID)
851839b9096538f790a2bb060547df24703807cb83bHal Finkel      return false;
852839b9096538f790a2bb060547df24703807cb83bHal Finkel  }
853839b9096538f790a2bb060547df24703807cb83bHal Finkel
854839b9096538f790a2bb060547df24703807cb83bHal Finkel  // Make sure this is not tied to an output register (or otherwise
855839b9096538f790a2bb060547df24703807cb83bHal Finkel  // constrained). This is true for ST?UX registers, for example, which
856839b9096538f790a2bb060547df24703807cb83bHal Finkel  // are tied to their output registers.
857839b9096538f790a2bb060547df24703807cb83bHal Finkel  if (UseInfo->Constraints != 0)
858839b9096538f790a2bb060547df24703807cb83bHal Finkel    return false;
859839b9096538f790a2bb060547df24703807cb83bHal Finkel
860839b9096538f790a2bb060547df24703807cb83bHal Finkel  unsigned ZeroReg;
861839b9096538f790a2bb060547df24703807cb83bHal Finkel  if (UseInfo->isLookupPtrRegClass()) {
862839b9096538f790a2bb060547df24703807cb83bHal Finkel    bool isPPC64 = TM.getSubtargetImpl()->isPPC64();
863839b9096538f790a2bb060547df24703807cb83bHal Finkel    ZeroReg = isPPC64 ? PPC::ZERO8 : PPC::ZERO;
864839b9096538f790a2bb060547df24703807cb83bHal Finkel  } else {
865839b9096538f790a2bb060547df24703807cb83bHal Finkel    ZeroReg = UseInfo->RegClass == PPC::G8RC_NOX0RegClassID ?
866839b9096538f790a2bb060547df24703807cb83bHal Finkel              PPC::ZERO8 : PPC::ZERO;
867839b9096538f790a2bb060547df24703807cb83bHal Finkel  }
868839b9096538f790a2bb060547df24703807cb83bHal Finkel
869839b9096538f790a2bb060547df24703807cb83bHal Finkel  bool DeleteDef = MRI->hasOneNonDBGUse(Reg);
870839b9096538f790a2bb060547df24703807cb83bHal Finkel  UseMI->getOperand(UseIdx).setReg(ZeroReg);
871839b9096538f790a2bb060547df24703807cb83bHal Finkel
872839b9096538f790a2bb060547df24703807cb83bHal Finkel  if (DeleteDef)
873839b9096538f790a2bb060547df24703807cb83bHal Finkel    DefMI->eraseFromParent();
874839b9096538f790a2bb060547df24703807cb83bHal Finkel
875839b9096538f790a2bb060547df24703807cb83bHal Finkel  return true;
876839b9096538f790a2bb060547df24703807cb83bHal Finkel}
877839b9096538f790a2bb060547df24703807cb83bHal Finkel
878da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkelstatic bool MBBDefinesCTR(MachineBasicBlock &MBB) {
879da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel  for (MachineBasicBlock::iterator I = MBB.begin(), IE = MBB.end();
880da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel       I != IE; ++I)
881da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel    if (I->definesRegister(PPC::CTR) || I->definesRegister(PPC::CTR8))
882da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel      return true;
883da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel  return false;
884da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel}
885da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel
886da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel// We should make sure that, if we're going to predicate both sides of a
887da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel// condition (a diamond), that both sides don't define the counter register. We
888da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel// can predicate counter-decrement-based branches, but while that predicates
889da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel// the branching, it does not predicate the counter decrement. If we tried to
890da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel// merge the triangle into one predicated block, we'd decrement the counter
891da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel// twice.
892da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkelbool PPCInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB,
893da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel                     unsigned NumT, unsigned ExtraT,
894da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel                     MachineBasicBlock &FMBB,
895da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel                     unsigned NumF, unsigned ExtraF,
896da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel                     const BranchProbability &Probability) const {
897da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel  return !(MBBDefinesCTR(TMBB) && MBBDefinesCTR(FMBB));
898da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel}
899da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel
900da47e17a6f58bb4dae22d3e79c69fcb1d254ba44Hal Finkel
9017eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkelbool PPCInstrInfo::isPredicated(const MachineInstr *MI) const {
9024b040294816e49413c739825d801042bc76171a7Hal Finkel  // The predicated branches are identified by their type, not really by the
9034b040294816e49413c739825d801042bc76171a7Hal Finkel  // explicit presence of a predicate. Furthermore, some of them can be
9044b040294816e49413c739825d801042bc76171a7Hal Finkel  // predicated more than once. Because if conversion won't try to predicate
9054b040294816e49413c739825d801042bc76171a7Hal Finkel  // any instruction which already claims to be predicated (by returning true
9064b040294816e49413c739825d801042bc76171a7Hal Finkel  // here), always return false. In doing so, we let isPredicable() be the
9074b040294816e49413c739825d801042bc76171a7Hal Finkel  // final word on whether not the instruction can be (further) predicated.
9084b040294816e49413c739825d801042bc76171a7Hal Finkel
9094b040294816e49413c739825d801042bc76171a7Hal Finkel  return false;
9107eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel}
9117eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
9127eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkelbool PPCInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
9137eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  if (!MI->isTerminator())
9147eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    return false;
9157eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
9167eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  // Conditional branch is a special case.
9177eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  if (MI->isBranch() && !MI->isBarrier())
9187eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    return true;
9197eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
9207eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  return !isPredicated(MI);
9217eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel}
9227eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
9237eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkelbool PPCInstrInfo::PredicateInstruction(
9247eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel                     MachineInstr *MI,
9257eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel                     const SmallVectorImpl<MachineOperand> &Pred) const {
9267eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  unsigned OpC = MI->getOpcode();
9277eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  if (OpC == PPC::BLR) {
9287eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) {
9297eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel      bool isPPC64 = TM.getSubtargetImpl()->isPPC64();
9307eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel      MI->setDesc(get(Pred[0].getImm() ?
9317eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel                      (isPPC64 ? PPC::BDNZLR8 : PPC::BDNZLR) :
9327eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel                      (isPPC64 ? PPC::BDZLR8  : PPC::BDZLR)));
9337eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    } else {
9347eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel      MI->setDesc(get(PPC::BCLR));
9357eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel      MachineInstrBuilder(*MI->getParent()->getParent(), MI)
9367eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel        .addImm(Pred[0].getImm())
9377eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel        .addReg(Pred[1].getReg());
9387eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    }
9397eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
9407eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    return true;
9417eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  } else if (OpC == PPC::B) {
9427eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) {
9437eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel      bool isPPC64 = TM.getSubtargetImpl()->isPPC64();
9447eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel      MI->setDesc(get(Pred[0].getImm() ?
9457eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel                      (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :
9467eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel                      (isPPC64 ? PPC::BDZ8  : PPC::BDZ)));
9477eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    } else {
9487eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel      MachineBasicBlock *MBB = MI->getOperand(0).getMBB();
9497eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel      MI->RemoveOperand(0);
9507eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
9517eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel      MI->setDesc(get(PPC::BCC));
9527eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel      MachineInstrBuilder(*MI->getParent()->getParent(), MI)
9537eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel        .addImm(Pred[0].getImm())
9547eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel        .addReg(Pred[1].getReg())
9557eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel        .addMBB(MBB);
9567eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    }
9577eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
9587eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    return true;
95990dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel  } else if (OpC == PPC::BCTR  || OpC == PPC::BCTR8 ||
96090dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel             OpC == PPC::BCTRL || OpC == PPC::BCTRL8) {
96190dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel    if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR)
96290dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel      llvm_unreachable("Cannot predicate bctr[l] on the ctr register");
96390dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel
96490dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel    bool setLR = OpC == PPC::BCTRL || OpC == PPC::BCTRL8;
96590dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel    bool isPPC64 = TM.getSubtargetImpl()->isPPC64();
96690dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel    MI->setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8 : PPC::BCCTR8) :
96790dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel                              (setLR ? PPC::BCCTRL  : PPC::BCCTR)));
96890dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel    MachineInstrBuilder(*MI->getParent()->getParent(), MI)
96990dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel      .addImm(Pred[0].getImm())
97090dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel      .addReg(Pred[1].getReg());
97190dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel    return true;
9727eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  }
9737eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
9747eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  return false;
9757eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel}
9767eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
9777eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkelbool PPCInstrInfo::SubsumesPredicate(
9787eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel                     const SmallVectorImpl<MachineOperand> &Pred1,
9797eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel                     const SmallVectorImpl<MachineOperand> &Pred2) const {
9807eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  assert(Pred1.size() == 2 && "Invalid PPC first predicate");
9817eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  assert(Pred2.size() == 2 && "Invalid PPC second predicate");
9827eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
9837eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  if (Pred1[1].getReg() == PPC::CTR8 || Pred1[1].getReg() == PPC::CTR)
9847eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    return false;
9857eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  if (Pred2[1].getReg() == PPC::CTR8 || Pred2[1].getReg() == PPC::CTR)
9867eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    return false;
9877eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
9887eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  PPC::Predicate P1 = (PPC::Predicate) Pred1[0].getImm();
9897eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  PPC::Predicate P2 = (PPC::Predicate) Pred2[0].getImm();
9907eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
9917eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  if (P1 == P2)
9927eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    return true;
9937eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
9947eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  // Does P1 subsume P2, e.g. GE subsumes GT.
9957eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  if (P1 == PPC::PRED_LE &&
9967eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel      (P2 == PPC::PRED_LT || P2 == PPC::PRED_EQ))
9977eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    return true;
9987eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  if (P1 == PPC::PRED_GE &&
9997eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel      (P2 == PPC::PRED_GT || P2 == PPC::PRED_EQ))
10007eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    return true;
10017eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
10027eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  return false;
10037eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel}
10047eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
10057eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkelbool PPCInstrInfo::DefinesPredicate(MachineInstr *MI,
10067eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel                                    std::vector<MachineOperand> &Pred) const {
10077eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  // Note: At the present time, the contents of Pred from this function is
10087eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  // unused by IfConversion. This implementation follows ARM by pushing the
10097eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  // CR-defining operand. Because the 'DZ' and 'DNZ' count as types of
10107eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  // predicate, instructions defining CTR or CTR8 are also included as
10117eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  // predicate-defining instructions.
10127eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
10137eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  const TargetRegisterClass *RCs[] =
10147eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    { &PPC::CRRCRegClass, &PPC::CRBITRCRegClass,
10157eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel      &PPC::CTRRCRegClass, &PPC::CTRRC8RegClass };
10167eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
10177eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  bool Found = false;
10187eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
10197eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    const MachineOperand &MO = MI->getOperand(i);
10204e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel    for (unsigned c = 0; c < array_lengthof(RCs) && !Found; ++c) {
10217eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel      const TargetRegisterClass *RC = RCs[c];
10224e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel      if (MO.isReg()) {
10234e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel        if (MO.isDef() && RC->contains(MO.getReg())) {
10247eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel          Pred.push_back(MO);
10257eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel          Found = true;
10267eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel        }
10274e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel      } else if (MO.isRegMask()) {
10284e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel        for (TargetRegisterClass::iterator I = RC->begin(),
10294e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel             IE = RC->end(); I != IE; ++I)
10304e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel          if (MO.clobbersPhysReg(*I)) {
10314e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel            Pred.push_back(MO);
10324e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel            Found = true;
10334e3172867d0c1acfda9d2cc88dfad23634e649ebHal Finkel          }
10347eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel      }
10357eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    }
10367eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  }
10377eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
10387eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  return Found;
10397eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel}
10407eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
10417eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkelbool PPCInstrInfo::isPredicable(MachineInstr *MI) const {
10427eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  unsigned OpC = MI->getOpcode();
10437eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  switch (OpC) {
10447eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  default:
10457eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    return false;
10467eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  case PPC::B:
10477eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  case PPC::BLR:
104890dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel  case PPC::BCTR:
104990dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel  case PPC::BCTR8:
105090dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel  case PPC::BCTRL:
105190dd7fd167b6d09e4a7f37e35dcbfdc492546a79Hal Finkel  case PPC::BCTRL8:
10527eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel    return true;
10537eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel  }
10547eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel}
10557eb0d8148e1210d9e31ab471477de47b53bab117Hal Finkel
1056860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkelbool PPCInstrInfo::analyzeCompare(const MachineInstr *MI,
1057860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel                                  unsigned &SrcReg, unsigned &SrcReg2,
1058860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel                                  int &Mask, int &Value) const {
1059860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  unsigned Opc = MI->getOpcode();
1060860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1061860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  switch (Opc) {
1062860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  default: return false;
1063860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  case PPC::CMPWI:
1064860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  case PPC::CMPLWI:
1065860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  case PPC::CMPDI:
1066860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  case PPC::CMPLDI:
1067860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    SrcReg = MI->getOperand(1).getReg();
1068860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    SrcReg2 = 0;
1069860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    Value = MI->getOperand(2).getImm();
1070860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    Mask = 0xFFFF;
1071860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    return true;
1072860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  case PPC::CMPW:
1073860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  case PPC::CMPLW:
1074860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  case PPC::CMPD:
1075860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  case PPC::CMPLD:
1076860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  case PPC::FCMPUS:
1077860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  case PPC::FCMPUD:
1078860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    SrcReg = MI->getOperand(1).getReg();
1079860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    SrcReg2 = MI->getOperand(2).getReg();
1080860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    return true;
1081860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  }
1082860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel}
108387c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel
1084860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkelbool PPCInstrInfo::optimizeCompareInstr(MachineInstr *CmpInstr,
1085860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel                                        unsigned SrcReg, unsigned SrcReg2,
1086860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel                                        int Mask, int Value,
1087860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel                                        const MachineRegisterInfo *MRI) const {
10884029c3feed5c9a5b0793e3da140ecaabef19e3feHal Finkel  if (DisableCmpOpt)
10894029c3feed5c9a5b0793e3da140ecaabef19e3feHal Finkel    return false;
10904029c3feed5c9a5b0793e3da140ecaabef19e3feHal Finkel
1091860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  int OpC = CmpInstr->getOpcode();
1092860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  unsigned CRReg = CmpInstr->getOperand(0).getReg();
1093b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel
1094b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel  // FP record forms set CR1 based on the execption status bits, not a
1095b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel  // comparison with zero.
1096b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel  if (OpC == PPC::FCMPUS || OpC == PPC::FCMPUD)
1097b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel    return false;
1098860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1099860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // The record forms set the condition register based on a signed comparison
1100860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // with zero (so says the ISA manual). This is not as straightforward as it
1101860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // seems, however, because this is always a 64-bit comparison on PPC64, even
1102860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // for instructions that are 32-bit in nature (like slw for example).
1103860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // So, on PPC32, for unsigned comparisons, we can use the record forms only
1104860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // for equality checks (as those don't depend on the sign). On PPC64,
1105860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // we are restricted to equality for unsigned 64-bit comparisons and for
1106860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // signed 32-bit comparisons the applicability is more restricted.
1107860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  bool isPPC64 = TM.getSubtargetImpl()->isPPC64();
1108860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  bool is32BitSignedCompare   = OpC ==  PPC::CMPWI || OpC == PPC::CMPW;
1109860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  bool is32BitUnsignedCompare = OpC == PPC::CMPLWI || OpC == PPC::CMPLW;
1110860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  bool is64BitUnsignedCompare = OpC == PPC::CMPLDI || OpC == PPC::CMPLD;
1111860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1112860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // Get the unique definition of SrcReg.
1113860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);
1114860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  if (!MI) return false;
1115860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  int MIOpC = MI->getOpcode();
1116860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1117860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  bool equalityOnly = false;
1118860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  bool noSub = false;
1119860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  if (isPPC64) {
1120860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    if (is32BitSignedCompare) {
1121860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      // We can perform this optimization only if MI is sign-extending.
1122860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      if (MIOpC == PPC::SRAW  || MIOpC == PPC::SRAWo ||
1123860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel          MIOpC == PPC::SRAWI || MIOpC == PPC::SRAWIo ||
1124860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel          MIOpC == PPC::EXTSB || MIOpC == PPC::EXTSBo ||
1125860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel          MIOpC == PPC::EXTSH || MIOpC == PPC::EXTSHo ||
1126860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel          MIOpC == PPC::EXTSW || MIOpC == PPC::EXTSWo) {
1127860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel        noSub = true;
1128860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      } else
1129860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel        return false;
1130860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    } else if (is32BitUnsignedCompare) {
1131860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      // We can perform this optimization, equality only, if MI is
1132860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      // zero-extending.
1133860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      if (MIOpC == PPC::CNTLZW || MIOpC == PPC::CNTLZWo ||
1134860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel          MIOpC == PPC::SLW    || MIOpC == PPC::SLWo ||
1135860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel          MIOpC == PPC::SRW    || MIOpC == PPC::SRWo) {
1136860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel        noSub = true;
1137860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel        equalityOnly = true;
1138860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      } else
1139860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel        return false;
1140b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel    } else
1141860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      equalityOnly = is64BitUnsignedCompare;
1142b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel  } else
1143860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    equalityOnly = is32BitUnsignedCompare;
1144860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1145860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  if (equalityOnly) {
1146860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    // We need to check the uses of the condition register in order to reject
1147860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    // non-equality comparisons.
1148860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    for (MachineRegisterInfo::use_iterator I = MRI->use_begin(CRReg),
1149860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel         IE = MRI->use_end(); I != IE; ++I) {
1150860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      MachineInstr *UseMI = &*I;
1151860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      if (UseMI->getOpcode() == PPC::BCC) {
1152860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel        unsigned Pred = UseMI->getOperand(0).getImm();
11538a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel        if (Pred != PPC::PRED_EQ && Pred != PPC::PRED_NE)
11548a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel          return false;
1155860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      } else if (UseMI->getOpcode() == PPC::ISEL ||
1156860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel                 UseMI->getOpcode() == PPC::ISEL8) {
1157860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel        unsigned SubIdx = UseMI->getOperand(3).getSubReg();
11588a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel        if (SubIdx != PPC::sub_eq)
11598a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel          return false;
1160860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      } else
1161860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel        return false;
1162860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    }
1163860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  }
1164860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
11658a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel  MachineBasicBlock::iterator I = CmpInstr;
1166860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1167860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // Scan forward to find the first use of the compare.
1168860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  for (MachineBasicBlock::iterator EL = CmpInstr->getParent()->end();
1169860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel       I != EL; ++I) {
1170860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    bool FoundUse = false;
1171860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    for (MachineRegisterInfo::use_iterator J = MRI->use_begin(CRReg),
1172860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel         JE = MRI->use_end(); J != JE; ++J)
1173860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      if (&*J == &*I) {
1174860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel        FoundUse = true;
1175860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel        break;
1176860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      }
1177860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1178860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    if (FoundUse)
1179860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      break;
1180860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  }
1181860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1182860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // There are two possible candidates which can be changed to set CR[01].
1183860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // One is MI, the other is a SUB instruction.
1184860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // For CMPrr(r1,r2), we are looking for SUB(r1,r2) or SUB(r2,r1).
1185860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  MachineInstr *Sub = NULL;
1186860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  if (SrcReg2 != 0)
1187860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    // MI is not a candidate for CMPrr.
1188860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    MI = NULL;
1189860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // FIXME: Conservatively refuse to convert an instruction which isn't in the
1190860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // same BB as the comparison. This is to allow the check below to avoid calls
1191860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // (and other explicit clobbers); instead we should really check for these
1192860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // more explicitly (in at least a few predecessors).
1193860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  else if (MI->getParent() != CmpInstr->getParent() || Value != 0) {
1194860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    // PPC does not have a record-form SUBri.
1195860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    return false;
1196860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  }
1197860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1198860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // Search for Sub.
1199860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  const TargetRegisterInfo *TRI = &getRegisterInfo();
1200860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  --I;
12018a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel
12028a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel  // Get ready to iterate backward from CmpInstr.
12038a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel  MachineBasicBlock::iterator E = MI,
12048a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel                              B = CmpInstr->getParent()->begin();
12058a88cadaedcfa3bb020df1d100d67cecaf638f35Hal Finkel
1206860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  for (; I != E && !noSub; --I) {
1207860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    const MachineInstr &Instr = *I;
1208860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    unsigned IOpC = Instr.getOpcode();
1209860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1210860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    if (&*I != CmpInstr && (
1211b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel        Instr.modifiesRegister(PPC::CR0, TRI) ||
1212b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel        Instr.readsRegister(PPC::CR0, TRI)))
1213860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      // This instruction modifies or uses the record condition register after
1214860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      // the one we want to change. While we could do this transformation, it
1215860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      // would likely not be profitable. This transformation removes one
1216860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      // instruction, and so even forcing RA to generate one move probably
1217860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      // makes it unprofitable.
1218860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      return false;
1219860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1220860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    // Check whether CmpInstr can be made redundant by the current instruction.
1221860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    if ((OpC == PPC::CMPW || OpC == PPC::CMPLW ||
1222860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel         OpC == PPC::CMPD || OpC == PPC::CMPLD) &&
1223860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel        (IOpC == PPC::SUBF || IOpC == PPC::SUBF8) &&
1224860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel        ((Instr.getOperand(1).getReg() == SrcReg &&
1225860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel          Instr.getOperand(2).getReg() == SrcReg2) ||
1226860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel        (Instr.getOperand(1).getReg() == SrcReg2 &&
1227860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel         Instr.getOperand(2).getReg() == SrcReg))) {
1228860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      Sub = &*I;
1229860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      break;
1230860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    }
1231860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1232860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    if (I == B)
1233860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      // The 'and' is below the comparison instruction.
1234860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      return false;
1235860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  }
1236860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1237860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // Return false if no candidates exist.
1238860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  if (!MI && !Sub)
1239860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    return false;
1240860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1241860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // The single candidate is called MI.
1242860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  if (!MI) MI = Sub;
1243860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1244860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  int NewOpC = -1;
1245860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  MIOpC = MI->getOpcode();
1246860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  if (MIOpC == PPC::ANDIo || MIOpC == PPC::ANDIo8)
1247860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    NewOpC = MIOpC;
1248860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  else {
1249860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    NewOpC = PPC::getRecordFormOpcode(MIOpC);
1250860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    if (NewOpC == -1 && PPC::getNonRecordFormOpcode(MIOpC) != -1)
1251860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      NewOpC = MIOpC;
1252860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  }
1253860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1254860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // FIXME: On the non-embedded POWER architectures, only some of the record
1255860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // forms are fast, and we should use only the fast ones.
1256860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1257860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // The defining instruction has a record form (or is already a record
1258860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // form). It is possible, however, that we'll need to reverse the condition
1259860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // code of the users.
1260860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  if (NewOpC == -1)
1261860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    return false;
1262860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
126387c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel  SmallVector<std::pair<MachineOperand*, PPC::Predicate>, 4> PredsToUpdate;
126487c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel  SmallVector<std::pair<MachineOperand*, unsigned>, 4> SubRegsToUpdate;
1265860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1266860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // If we have SUB(r1, r2) and CMP(r2, r1), the condition code based on CMP
1267860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // needs to be updated to be based on SUB.  Push the condition code
1268860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // operands to OperandsToUpdate.  If it is safe to remove CmpInstr, the
1269860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // condition code of these operands will be modified.
1270860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  bool ShouldSwap = false;
1271860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  if (Sub) {
1272860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    ShouldSwap = SrcReg2 != 0 && Sub->getOperand(1).getReg() == SrcReg2 &&
1273860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      Sub->getOperand(2).getReg() == SrcReg;
1274860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1275860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    // The operands to subf are the opposite of sub, so only in the fixed-point
1276860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    // case, invert the order.
1277b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel    ShouldSwap = !ShouldSwap;
1278860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  }
1279860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1280860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  if (ShouldSwap)
1281860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    for (MachineRegisterInfo::use_iterator I = MRI->use_begin(CRReg),
1282860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel         IE = MRI->use_end(); I != IE; ++I) {
1283860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      MachineInstr *UseMI = &*I;
1284860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      if (UseMI->getOpcode() == PPC::BCC) {
1285860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel        PPC::Predicate Pred = (PPC::Predicate) UseMI->getOperand(0).getImm();
128687c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel        assert((!equalityOnly ||
128787c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel                Pred == PPC::PRED_EQ || Pred == PPC::PRED_NE) &&
128887c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel               "Invalid predicate for equality-only optimization");
128987c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel        PredsToUpdate.push_back(std::make_pair(&((*I).getOperand(0)),
1290abe64dc6f7363c7e6170568e382fb06d81d62f51Hal Finkel                                PPC::getSwappedPredicate(Pred)));
1291860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      } else if (UseMI->getOpcode() == PPC::ISEL ||
1292860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel                 UseMI->getOpcode() == PPC::ISEL8) {
129387c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel        unsigned NewSubReg = UseMI->getOperand(3).getSubReg();
129487c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel        assert((!equalityOnly || NewSubReg == PPC::sub_eq) &&
129587c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel               "Invalid CR bit for equality-only optimization");
129687c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel
129787c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel        if (NewSubReg == PPC::sub_lt)
129887c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel          NewSubReg = PPC::sub_gt;
129987c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel        else if (NewSubReg == PPC::sub_gt)
130087c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel          NewSubReg = PPC::sub_lt;
130187c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel
130287c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel        SubRegsToUpdate.push_back(std::make_pair(&((*I).getOperand(3)),
130387c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel                                                 NewSubReg));
1304860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      } else // We need to abort on a user we don't understand.
1305860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel        return false;
1306860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    }
1307860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1308860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // Create a new virtual register to hold the value of the CR set by the
1309860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // record-form instruction. If the instruction was not previously in
1310860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // record form, then set the kill flag on the CR.
1311860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  CmpInstr->eraseFromParent();
1312860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1313860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  MachineBasicBlock::iterator MII = MI;
1314860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  BuildMI(*MI->getParent(), llvm::next(MII), MI->getDebugLoc(),
1315860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel          get(TargetOpcode::COPY), CRReg)
1316b45eb9fd275f857788cabb15ef8aabf0ff5907ccHal Finkel    .addReg(PPC::CR0, MIOpC != NewOpC ? RegState::Kill : 0);
1317860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1318860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  if (MIOpC != NewOpC) {
1319860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    // We need to be careful here: we're replacing one instruction with
1320860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    // another, and we need to make sure that we get all of the right
1321860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    // implicit uses and defs. On the other hand, the caller may be holding
1322860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    // an iterator to this instruction, and so we can't delete it (this is
1323860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    // specifically the case if this is the instruction directly after the
1324860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    // compare).
1325860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1326860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    const MCInstrDesc &NewDesc = get(NewOpC);
1327860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    MI->setDesc(NewDesc);
1328860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1329860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    if (NewDesc.ImplicitDefs)
1330860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      for (const uint16_t *ImpDefs = NewDesc.getImplicitDefs();
1331860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel           *ImpDefs; ++ImpDefs)
1332860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel        if (!MI->definesRegister(*ImpDefs))
1333860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel          MI->addOperand(*MI->getParent()->getParent(),
1334860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel                         MachineOperand::CreateReg(*ImpDefs, true, true));
1335860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel    if (NewDesc.ImplicitUses)
1336860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel      for (const uint16_t *ImpUses = NewDesc.getImplicitUses();
1337860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel           *ImpUses; ++ImpUses)
1338860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel        if (!MI->readsRegister(*ImpUses))
1339860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel          MI->addOperand(*MI->getParent()->getParent(),
1340860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel                         MachineOperand::CreateReg(*ImpUses, false, true));
1341860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  }
1342860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1343860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // Modify the condition code of operands in OperandsToUpdate.
1344860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // Since we have SUB(r1, r2) and CMP(r2, r1), the condition code needs to
1345860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  // be changed from r2 > r1 to r1 < r2, from r2 < r1 to r1 > r2, etc.
134687c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel  for (unsigned i = 0, e = PredsToUpdate.size(); i < e; i++)
134787c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel    PredsToUpdate[i].first->setImm(PredsToUpdate[i].second);
1348860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
134987c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel  for (unsigned i = 0, e = SubRegsToUpdate.size(); i < e; i++)
135087c1e42be7dadaea7c3e00fb7ccbd77633cea37fHal Finkel    SubRegsToUpdate[i].first->setSubReg(SubRegsToUpdate[i].second);
1351860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
1352860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel  return true;
1353860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel}
1354860c08cad5b7c1359123bb2b0e74df4b6e48a15cHal Finkel
135552e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray/// GetInstSize - Return the number of bytes of code the specified
135652e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray/// instruction may be.  This returns the maximum number of bytes.
135752e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray///
135852e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffrayunsigned PPCInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
135952e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray  switch (MI->getOpcode()) {
136052e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray  case PPC::INLINEASM: {       // Inline Asm: Variable size.
136152e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray    const MachineFunction *MF = MI->getParent()->getParent();
136252e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray    const char *AsmStr = MI->getOperand(0).getSymbolName();
1363af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner    return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
136452e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray  }
13657431beaba2a01c3fe299c861b2ec85cbf1dc81c4Bill Wendling  case PPC::PROLOG_LABEL:
13664406604047423576e36657c7ede266ca42e79642Dan Gohman  case PPC::EH_LABEL:
13674406604047423576e36657c7ede266ca42e79642Dan Gohman  case PPC::GC_LABEL:
1368375be7730a6f3dee7a6dc319ee6c355a11ac99adDale Johannesen  case PPC::DBG_VALUE:
136952e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray    return 0;
137086765fbe170198e7bb40fd8499d1354f4c786f60Ulrich Weigand  case PPC::BL8_NOP:
137186765fbe170198e7bb40fd8499d1354f4c786f60Ulrich Weigand  case PPC::BLA8_NOP:
13725b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel    return 8;
137352e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray  default:
137452e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray    return 4; // PowerPC instructions are all 4 bytes
137552e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray  }
137652e724ad7e679ee590f4bd763d55280586a8f1bcNicolas Geoffray}
13775ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
13785ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel#undef DEBUG_TYPE
13795ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel#define DEBUG_TYPE "ppc-early-ret"
13805ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal FinkelSTATISTIC(NumBCLR, "Number of early conditional returns");
13815ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal FinkelSTATISTIC(NumBLR,  "Number of early returns");
13825ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
13835ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkelnamespace llvm {
13845ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel  void initializePPCEarlyReturnPass(PassRegistry&);
13855ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel}
13865ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
13875ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkelnamespace {
13885ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel  // PPCEarlyReturn pass - For simple functions without epilogue code, move
13895ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel  // returns up, and create conditional returns, to avoid unnecessary
13905ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel  // branch-to-blr sequences.
13915ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel  struct PPCEarlyReturn : public MachineFunctionPass {
13925ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel    static char ID;
13935ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel    PPCEarlyReturn() : MachineFunctionPass(ID) {
13945ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel      initializePPCEarlyReturnPass(*PassRegistry::getPassRegistry());
13955ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel    }
13965ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
13975ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel    const PPCTargetMachine *TM;
13985ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel    const PPCInstrInfo *TII;
13995ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
14005ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkelprotected:
140113049aef8ad86795e94006dea0e097a8add85665Hal Finkel    bool processBlock(MachineBasicBlock &ReturnMBB) {
14025ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel      bool Changed = false;
14035ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
140413049aef8ad86795e94006dea0e097a8add85665Hal Finkel      MachineBasicBlock::iterator I = ReturnMBB.begin();
140513049aef8ad86795e94006dea0e097a8add85665Hal Finkel      I = ReturnMBB.SkipPHIsAndLabels(I);
14065ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
14075ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel      // The block must be essentially empty except for the blr.
140813049aef8ad86795e94006dea0e097a8add85665Hal Finkel      if (I == ReturnMBB.end() || I->getOpcode() != PPC::BLR ||
140913049aef8ad86795e94006dea0e097a8add85665Hal Finkel          I != ReturnMBB.getLastNonDebugInstr())
14105ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel        return Changed;
14115ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
14125ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel      SmallVector<MachineBasicBlock*, 8> PredToRemove;
141313049aef8ad86795e94006dea0e097a8add85665Hal Finkel      for (MachineBasicBlock::pred_iterator PI = ReturnMBB.pred_begin(),
141413049aef8ad86795e94006dea0e097a8add85665Hal Finkel           PIE = ReturnMBB.pred_end(); PI != PIE; ++PI) {
14155ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel        bool OtherReference = false, BlockChanged = false;
141613049aef8ad86795e94006dea0e097a8add85665Hal Finkel        for (MachineBasicBlock::iterator J = (*PI)->getLastNonDebugInstr();;) {
14175ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel          if (J->getOpcode() == PPC::B) {
141813049aef8ad86795e94006dea0e097a8add85665Hal Finkel            if (J->getOperand(0).getMBB() == &ReturnMBB) {
14195ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel              // This is an unconditional branch to the return. Replace the
14205ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel	      // branch with a blr.
14215ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel              BuildMI(**PI, J, J->getDebugLoc(), TII->get(PPC::BLR));
142213049aef8ad86795e94006dea0e097a8add85665Hal Finkel              MachineBasicBlock::iterator K = J--;
14235ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel              K->eraseFromParent();
14245ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel              BlockChanged = true;
14255ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel              ++NumBLR;
14265ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel              continue;
14275ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel            }
14285ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel          } else if (J->getOpcode() == PPC::BCC) {
142913049aef8ad86795e94006dea0e097a8add85665Hal Finkel            if (J->getOperand(2).getMBB() == &ReturnMBB) {
14305ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel              // This is a conditional branch to the return. Replace the branch
14315ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel              // with a bclr.
14325ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel              BuildMI(**PI, J, J->getDebugLoc(), TII->get(PPC::BCLR))
14335ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel                .addImm(J->getOperand(0).getImm())
14345ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel                .addReg(J->getOperand(1).getReg());
143513049aef8ad86795e94006dea0e097a8add85665Hal Finkel              MachineBasicBlock::iterator K = J--;
14365ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel              K->eraseFromParent();
14375ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel              BlockChanged = true;
14385ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel              ++NumBCLR;
14395ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel              continue;
14405ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel            }
14415ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel          } else if (J->isBranch()) {
14425ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel            if (J->isIndirectBranch()) {
144313049aef8ad86795e94006dea0e097a8add85665Hal Finkel              if (ReturnMBB.hasAddressTaken())
14445ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel                OtherReference = true;
14455ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel            } else
14465ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel              for (unsigned i = 0; i < J->getNumOperands(); ++i)
14475ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel                if (J->getOperand(i).isMBB() &&
144813049aef8ad86795e94006dea0e097a8add85665Hal Finkel                    J->getOperand(i).getMBB() == &ReturnMBB)
14495ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel                  OtherReference = true;
145013049aef8ad86795e94006dea0e097a8add85665Hal Finkel          } else if (!J->isTerminator() && !J->isDebugValue())
145113049aef8ad86795e94006dea0e097a8add85665Hal Finkel            break;
14525ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
145313049aef8ad86795e94006dea0e097a8add85665Hal Finkel          if (J == (*PI)->begin())
145413049aef8ad86795e94006dea0e097a8add85665Hal Finkel            break;
145513049aef8ad86795e94006dea0e097a8add85665Hal Finkel
145613049aef8ad86795e94006dea0e097a8add85665Hal Finkel          --J;
14575ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel        }
14585ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
145913049aef8ad86795e94006dea0e097a8add85665Hal Finkel        if ((*PI)->canFallThrough() && (*PI)->isLayoutSuccessor(&ReturnMBB))
14605ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel          OtherReference = true;
14615ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
14625ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel	// Predecessors are stored in a vector and can't be removed here.
14635ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel        if (!OtherReference && BlockChanged) {
14645ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel          PredToRemove.push_back(*PI);
14655ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel        }
14665ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
14675ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel        if (BlockChanged)
14685ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel          Changed = true;
14695ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel      }
14705ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
14715ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel      for (unsigned i = 0, ie = PredToRemove.size(); i != ie; ++i)
147213049aef8ad86795e94006dea0e097a8add85665Hal Finkel        PredToRemove[i]->removeSuccessor(&ReturnMBB);
14735ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
147413049aef8ad86795e94006dea0e097a8add85665Hal Finkel      if (Changed && !ReturnMBB.hasAddressTaken()) {
14755ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel        // We now might be able to merge this blr-only block into its
14765ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel        // by-layout predecessor.
147713049aef8ad86795e94006dea0e097a8add85665Hal Finkel        if (ReturnMBB.pred_size() == 1 &&
147813049aef8ad86795e94006dea0e097a8add85665Hal Finkel            (*ReturnMBB.pred_begin())->isLayoutSuccessor(&ReturnMBB)) {
14795ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel          // Move the blr into the preceding block.
148013049aef8ad86795e94006dea0e097a8add85665Hal Finkel          MachineBasicBlock &PrevMBB = **ReturnMBB.pred_begin();
148113049aef8ad86795e94006dea0e097a8add85665Hal Finkel          PrevMBB.splice(PrevMBB.end(), &ReturnMBB, I);
148213049aef8ad86795e94006dea0e097a8add85665Hal Finkel          PrevMBB.removeSuccessor(&ReturnMBB);
14835ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel        }
14845ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
148513049aef8ad86795e94006dea0e097a8add85665Hal Finkel        if (ReturnMBB.pred_empty())
148613049aef8ad86795e94006dea0e097a8add85665Hal Finkel          ReturnMBB.eraseFromParent();
14875ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel      }
14885ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
14895ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel      return Changed;
14905ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel    }
14915ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
14925ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkelpublic:
14935ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel    virtual bool runOnMachineFunction(MachineFunction &MF) {
14945ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel      TM = static_cast<const PPCTargetMachine *>(&MF.getTarget());
14955ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel      TII = TM->getInstrInfo();
14965ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
14975ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel      bool Changed = false;
14985ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
149913049aef8ad86795e94006dea0e097a8add85665Hal Finkel      // If the function does not have at least two blocks, then there is
15005ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel      // nothing to do.
15015ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel      if (MF.size() < 2)
15025ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel        return Changed;
15035ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
15045ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel      for (MachineFunction::iterator I = MF.begin(); I != MF.end();) {
15055ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel        MachineBasicBlock &B = *I++;
15065ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel        if (processBlock(B))
15075ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel          Changed = true;
15085ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel      }
15095ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
15105ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel      return Changed;
15115ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel    }
15125ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
15135ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
15145ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel      MachineFunctionPass::getAnalysisUsage(AU);
15155ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel    }
15165ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel  };
15175ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel}
15185ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
15195ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal FinkelINITIALIZE_PASS(PPCEarlyReturn, DEBUG_TYPE,
15205ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel                "PowerPC Early-Return Creation", false, false)
15215ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
15225ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkelchar PPCEarlyReturn::ID = 0;
15235ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal FinkelFunctionPass*
15245ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkelllvm::createPPCEarlyReturnPass() { return new PPCEarlyReturn(); }
15255ee67e8e76dfcaffa5e776ef3d5eeb80807a627bHal Finkel
1526