Home | History | Annotate | Download | only in Alpha
      1 //===- AlphaInstrInfo.cpp - Alpha Instruction Information -------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file contains the Alpha implementation of the TargetInstrInfo class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "Alpha.h"
     15 #include "AlphaInstrInfo.h"
     16 #include "AlphaMachineFunctionInfo.h"
     17 #include "llvm/CodeGen/MachineInstrBuilder.h"
     18 #include "llvm/CodeGen/MachineRegisterInfo.h"
     19 #include "llvm/ADT/STLExtras.h"
     20 #include "llvm/ADT/SmallVector.h"
     21 #include "llvm/Support/ErrorHandling.h"
     22 
     23 #define GET_INSTRINFO_CTOR
     24 #include "AlphaGenInstrInfo.inc"
     25 using namespace llvm;
     26 
     27 AlphaInstrInfo::AlphaInstrInfo()
     28   : AlphaGenInstrInfo(Alpha::ADJUSTSTACKDOWN, Alpha::ADJUSTSTACKUP),
     29     RI(*this) {
     30 }
     31 
     32 
     33 unsigned
     34 AlphaInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
     35                                     int &FrameIndex) const {
     36   switch (MI->getOpcode()) {
     37   case Alpha::LDL:
     38   case Alpha::LDQ:
     39   case Alpha::LDBU:
     40   case Alpha::LDWU:
     41   case Alpha::LDS:
     42   case Alpha::LDT:
     43     if (MI->getOperand(1).isFI()) {
     44       FrameIndex = MI->getOperand(1).getIndex();
     45       return MI->getOperand(0).getReg();
     46     }
     47     break;
     48   }
     49   return 0;
     50 }
     51 
     52 unsigned
     53 AlphaInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
     54                                    int &FrameIndex) const {
     55   switch (MI->getOpcode()) {
     56   case Alpha::STL:
     57   case Alpha::STQ:
     58   case Alpha::STB:
     59   case Alpha::STW:
     60   case Alpha::STS:
     61   case Alpha::STT:
     62     if (MI->getOperand(1).isFI()) {
     63       FrameIndex = MI->getOperand(1).getIndex();
     64       return MI->getOperand(0).getReg();
     65     }
     66     break;
     67   }
     68   return 0;
     69 }
     70 
     71 static bool isAlphaIntCondCode(unsigned Opcode) {
     72   switch (Opcode) {
     73   case Alpha::BEQ:
     74   case Alpha::BNE:
     75   case Alpha::BGE:
     76   case Alpha::BGT:
     77   case Alpha::BLE:
     78   case Alpha::BLT:
     79   case Alpha::BLBC:
     80   case Alpha::BLBS:
     81     return true;
     82   default:
     83     return false;
     84   }
     85 }
     86 
     87 unsigned AlphaInstrInfo::InsertBranch(MachineBasicBlock &MBB,
     88                                       MachineBasicBlock *TBB,
     89                                       MachineBasicBlock *FBB,
     90                                       const SmallVectorImpl<MachineOperand> &Cond,
     91                                       DebugLoc DL) const {
     92   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
     93   assert((Cond.size() == 2 || Cond.size() == 0) &&
     94          "Alpha branch conditions have two components!");
     95 
     96   // One-way branch.
     97   if (FBB == 0) {
     98     if (Cond.empty())   // Unconditional branch
     99       BuildMI(&MBB, DL, get(Alpha::BR)).addMBB(TBB);
    100     else                // Conditional branch
    101       if (isAlphaIntCondCode(Cond[0].getImm()))
    102         BuildMI(&MBB, DL, get(Alpha::COND_BRANCH_I))
    103           .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
    104       else
    105         BuildMI(&MBB, DL, get(Alpha::COND_BRANCH_F))
    106           .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
    107     return 1;
    108   }
    109 
    110   // Two-way Conditional Branch.
    111   if (isAlphaIntCondCode(Cond[0].getImm()))
    112     BuildMI(&MBB, DL, get(Alpha::COND_BRANCH_I))
    113       .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
    114   else
    115     BuildMI(&MBB, DL, get(Alpha::COND_BRANCH_F))
    116       .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB);
    117   BuildMI(&MBB, DL, get(Alpha::BR)).addMBB(FBB);
    118   return 2;
    119 }
    120 
    121 void AlphaInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
    122                                  MachineBasicBlock::iterator MI, DebugLoc DL,
    123                                  unsigned DestReg, unsigned SrcReg,
    124                                  bool KillSrc) const {
    125   if (Alpha::GPRCRegClass.contains(DestReg, SrcReg)) {
    126     BuildMI(MBB, MI, DL, get(Alpha::BISr), DestReg)
    127       .addReg(SrcReg)
    128       .addReg(SrcReg, getKillRegState(KillSrc));
    129   } else if (Alpha::F4RCRegClass.contains(DestReg, SrcReg)) {
    130     BuildMI(MBB, MI, DL, get(Alpha::CPYSS), DestReg)
    131       .addReg(SrcReg)
    132       .addReg(SrcReg, getKillRegState(KillSrc));
    133   } else if (Alpha::F8RCRegClass.contains(DestReg, SrcReg)) {
    134     BuildMI(MBB, MI, DL, get(Alpha::CPYST), DestReg)
    135       .addReg(SrcReg)
    136       .addReg(SrcReg, getKillRegState(KillSrc));
    137   } else {
    138     llvm_unreachable("Attempt to copy register that is not GPR or FPR");
    139   }
    140 }
    141 
    142 void
    143 AlphaInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
    144                                     MachineBasicBlock::iterator MI,
    145                                     unsigned SrcReg, bool isKill, int FrameIdx,
    146                                     const TargetRegisterClass *RC,
    147                                     const TargetRegisterInfo *TRI) const {
    148   //cerr << "Trying to store " << getPrettyName(SrcReg) << " to "
    149   //     << FrameIdx << "\n";
    150   //BuildMI(MBB, MI, Alpha::WTF, 0).addReg(SrcReg);
    151 
    152   DebugLoc DL;
    153   if (MI != MBB.end()) DL = MI->getDebugLoc();
    154 
    155   if (RC == Alpha::F4RCRegisterClass)
    156     BuildMI(MBB, MI, DL, get(Alpha::STS))
    157       .addReg(SrcReg, getKillRegState(isKill))
    158       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
    159   else if (RC == Alpha::F8RCRegisterClass)
    160     BuildMI(MBB, MI, DL, get(Alpha::STT))
    161       .addReg(SrcReg, getKillRegState(isKill))
    162       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
    163   else if (RC == Alpha::GPRCRegisterClass)
    164     BuildMI(MBB, MI, DL, get(Alpha::STQ))
    165       .addReg(SrcReg, getKillRegState(isKill))
    166       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
    167   else
    168     llvm_unreachable("Unhandled register class");
    169 }
    170 
    171 void
    172 AlphaInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
    173                                         MachineBasicBlock::iterator MI,
    174                                         unsigned DestReg, int FrameIdx,
    175                                      const TargetRegisterClass *RC,
    176                                      const TargetRegisterInfo *TRI) const {
    177   //cerr << "Trying to load " << getPrettyName(DestReg) << " to "
    178   //     << FrameIdx << "\n";
    179   DebugLoc DL;
    180   if (MI != MBB.end()) DL = MI->getDebugLoc();
    181 
    182   if (RC == Alpha::F4RCRegisterClass)
    183     BuildMI(MBB, MI, DL, get(Alpha::LDS), DestReg)
    184       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
    185   else if (RC == Alpha::F8RCRegisterClass)
    186     BuildMI(MBB, MI, DL, get(Alpha::LDT), DestReg)
    187       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
    188   else if (RC == Alpha::GPRCRegisterClass)
    189     BuildMI(MBB, MI, DL, get(Alpha::LDQ), DestReg)
    190       .addFrameIndex(FrameIdx).addReg(Alpha::F31);
    191   else
    192     llvm_unreachable("Unhandled register class");
    193 }
    194 
    195 static unsigned AlphaRevCondCode(unsigned Opcode) {
    196   switch (Opcode) {
    197   case Alpha::BEQ: return Alpha::BNE;
    198   case Alpha::BNE: return Alpha::BEQ;
    199   case Alpha::BGE: return Alpha::BLT;
    200   case Alpha::BGT: return Alpha::BLE;
    201   case Alpha::BLE: return Alpha::BGT;
    202   case Alpha::BLT: return Alpha::BGE;
    203   case Alpha::BLBC: return Alpha::BLBS;
    204   case Alpha::BLBS: return Alpha::BLBC;
    205   case Alpha::FBEQ: return Alpha::FBNE;
    206   case Alpha::FBNE: return Alpha::FBEQ;
    207   case Alpha::FBGE: return Alpha::FBLT;
    208   case Alpha::FBGT: return Alpha::FBLE;
    209   case Alpha::FBLE: return Alpha::FBGT;
    210   case Alpha::FBLT: return Alpha::FBGE;
    211   default:
    212     llvm_unreachable("Unknown opcode");
    213   }
    214   return 0; // Not reached
    215 }
    216 
    217 // Branch analysis.
    218 bool AlphaInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB,
    219                                    MachineBasicBlock *&FBB,
    220                                    SmallVectorImpl<MachineOperand> &Cond,
    221                                    bool AllowModify) const {
    222   // If the block has no terminators, it just falls into the block after it.
    223   MachineBasicBlock::iterator I = MBB.end();
    224   if (I == MBB.begin())
    225     return false;
    226   --I;
    227   while (I->isDebugValue()) {
    228     if (I == MBB.begin())
    229       return false;
    230     --I;
    231   }
    232   if (!isUnpredicatedTerminator(I))
    233     return false;
    234 
    235   // Get the last instruction in the block.
    236   MachineInstr *LastInst = I;
    237 
    238   // If there is only one terminator instruction, process it.
    239   if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) {
    240     if (LastInst->getOpcode() == Alpha::BR) {
    241       TBB = LastInst->getOperand(0).getMBB();
    242       return false;
    243     } else if (LastInst->getOpcode() == Alpha::COND_BRANCH_I ||
    244                LastInst->getOpcode() == Alpha::COND_BRANCH_F) {
    245       // Block ends with fall-through condbranch.
    246       TBB = LastInst->getOperand(2).getMBB();
    247       Cond.push_back(LastInst->getOperand(0));
    248       Cond.push_back(LastInst->getOperand(1));
    249       return false;
    250     }
    251     // Otherwise, don't know what this is.
    252     return true;
    253   }
    254 
    255   // Get the instruction before it if it's a terminator.
    256   MachineInstr *SecondLastInst = I;
    257 
    258   // If there are three terminators, we don't know what sort of block this is.
    259   if (SecondLastInst && I != MBB.begin() &&
    260       isUnpredicatedTerminator(--I))
    261     return true;
    262 
    263   // If the block ends with Alpha::BR and Alpha::COND_BRANCH_*, handle it.
    264   if ((SecondLastInst->getOpcode() == Alpha::COND_BRANCH_I ||
    265       SecondLastInst->getOpcode() == Alpha::COND_BRANCH_F) &&
    266       LastInst->getOpcode() == Alpha::BR) {
    267     TBB =  SecondLastInst->getOperand(2).getMBB();
    268     Cond.push_back(SecondLastInst->getOperand(0));
    269     Cond.push_back(SecondLastInst->getOperand(1));
    270     FBB = LastInst->getOperand(0).getMBB();
    271     return false;
    272   }
    273 
    274   // If the block ends with two Alpha::BRs, handle it.  The second one is not
    275   // executed, so remove it.
    276   if (SecondLastInst->getOpcode() == Alpha::BR &&
    277       LastInst->getOpcode() == Alpha::BR) {
    278     TBB = SecondLastInst->getOperand(0).getMBB();
    279     I = LastInst;
    280     if (AllowModify)
    281       I->eraseFromParent();
    282     return false;
    283   }
    284 
    285   // Otherwise, can't handle this.
    286   return true;
    287 }
    288 
    289 unsigned AlphaInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
    290   MachineBasicBlock::iterator I = MBB.end();
    291   if (I == MBB.begin()) return 0;
    292   --I;
    293   while (I->isDebugValue()) {
    294     if (I == MBB.begin())
    295       return 0;
    296     --I;
    297   }
    298   if (I->getOpcode() != Alpha::BR &&
    299       I->getOpcode() != Alpha::COND_BRANCH_I &&
    300       I->getOpcode() != Alpha::COND_BRANCH_F)
    301     return 0;
    302 
    303   // Remove the branch.
    304   I->eraseFromParent();
    305 
    306   I = MBB.end();
    307 
    308   if (I == MBB.begin()) return 1;
    309   --I;
    310   if (I->getOpcode() != Alpha::COND_BRANCH_I &&
    311       I->getOpcode() != Alpha::COND_BRANCH_F)
    312     return 1;
    313 
    314   // Remove the branch.
    315   I->eraseFromParent();
    316   return 2;
    317 }
    318 
    319 void AlphaInstrInfo::insertNoop(MachineBasicBlock &MBB,
    320                                 MachineBasicBlock::iterator MI) const {
    321   DebugLoc DL;
    322   BuildMI(MBB, MI, DL, get(Alpha::BISr), Alpha::R31)
    323     .addReg(Alpha::R31)
    324     .addReg(Alpha::R31);
    325 }
    326 
    327 bool AlphaInstrInfo::
    328 ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
    329   assert(Cond.size() == 2 && "Invalid Alpha branch opcode!");
    330   Cond[0].setImm(AlphaRevCondCode(Cond[0].getImm()));
    331   return false;
    332 }
    333 
    334 /// getGlobalBaseReg - Return a virtual register initialized with the
    335 /// the global base register value. Output instructions required to
    336 /// initialize the register in the function entry block, if necessary.
    337 ///
    338 unsigned AlphaInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
    339   AlphaMachineFunctionInfo *AlphaFI = MF->getInfo<AlphaMachineFunctionInfo>();
    340   unsigned GlobalBaseReg = AlphaFI->getGlobalBaseReg();
    341   if (GlobalBaseReg != 0)
    342     return GlobalBaseReg;
    343 
    344   // Insert the set of GlobalBaseReg into the first MBB of the function
    345   MachineBasicBlock &FirstMBB = MF->front();
    346   MachineBasicBlock::iterator MBBI = FirstMBB.begin();
    347   MachineRegisterInfo &RegInfo = MF->getRegInfo();
    348   const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
    349 
    350   GlobalBaseReg = RegInfo.createVirtualRegister(&Alpha::GPRCRegClass);
    351   BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY),
    352           GlobalBaseReg).addReg(Alpha::R29);
    353   RegInfo.addLiveIn(Alpha::R29);
    354 
    355   AlphaFI->setGlobalBaseReg(GlobalBaseReg);
    356   return GlobalBaseReg;
    357 }
    358 
    359 /// getGlobalRetAddr - Return a virtual register initialized with the
    360 /// the global base register value. Output instructions required to
    361 /// initialize the register in the function entry block, if necessary.
    362 ///
    363 unsigned AlphaInstrInfo::getGlobalRetAddr(MachineFunction *MF) const {
    364   AlphaMachineFunctionInfo *AlphaFI = MF->getInfo<AlphaMachineFunctionInfo>();
    365   unsigned GlobalRetAddr = AlphaFI->getGlobalRetAddr();
    366   if (GlobalRetAddr != 0)
    367     return GlobalRetAddr;
    368 
    369   // Insert the set of GlobalRetAddr into the first MBB of the function
    370   MachineBasicBlock &FirstMBB = MF->front();
    371   MachineBasicBlock::iterator MBBI = FirstMBB.begin();
    372   MachineRegisterInfo &RegInfo = MF->getRegInfo();
    373   const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
    374 
    375   GlobalRetAddr = RegInfo.createVirtualRegister(&Alpha::GPRCRegClass);
    376   BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY),
    377           GlobalRetAddr).addReg(Alpha::R26);
    378   RegInfo.addLiveIn(Alpha::R26);
    379 
    380   AlphaFI->setGlobalRetAddr(GlobalRetAddr);
    381   return GlobalRetAddr;
    382 }
    383