Home | History | Annotate | Download | only in Blackfin
      1 //===- BlackfinInstrInfo.cpp - Blackfin 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 Blackfin implementation of the TargetInstrInfo class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "BlackfinInstrInfo.h"
     15 #include "BlackfinSubtarget.h"
     16 #include "Blackfin.h"
     17 #include "llvm/CodeGen/MachineRegisterInfo.h"
     18 #include "llvm/CodeGen/MachineInstrBuilder.h"
     19 #include "llvm/ADT/STLExtras.h"
     20 #include "llvm/ADT/SmallVector.h"
     21 #include "llvm/Support/ErrorHandling.h"
     22 #include "llvm/Support/TargetRegistry.h"
     23 
     24 #define GET_INSTRINFO_CTOR
     25 #include "BlackfinGenInstrInfo.inc"
     26 
     27 using namespace llvm;
     28 
     29 BlackfinInstrInfo::BlackfinInstrInfo(BlackfinSubtarget &ST)
     30   : BlackfinGenInstrInfo(BF::ADJCALLSTACKDOWN, BF::ADJCALLSTACKUP),
     31     RI(ST, *this),
     32     Subtarget(ST) {}
     33 
     34 /// isLoadFromStackSlot - If the specified machine instruction is a direct
     35 /// load from a stack slot, return the virtual or physical register number of
     36 /// the destination along with the FrameIndex of the loaded stack slot.  If
     37 /// not, return 0.  This predicate must return 0 if the instruction has
     38 /// any side effects other than loading from the stack slot.
     39 unsigned BlackfinInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
     40                                                 int &FrameIndex) const {
     41   switch (MI->getOpcode()) {
     42   default: break;
     43   case BF::LOAD32fi:
     44   case BF::LOAD16fi:
     45     if (MI->getOperand(1).isFI() &&
     46         MI->getOperand(2).isImm() &&
     47         MI->getOperand(2).getImm() == 0) {
     48       FrameIndex = MI->getOperand(1).getIndex();
     49       return MI->getOperand(0).getReg();
     50     }
     51     break;
     52   }
     53   return 0;
     54 }
     55 
     56 /// isStoreToStackSlot - If the specified machine instruction is a direct
     57 /// store to a stack slot, return the virtual or physical register number of
     58 /// the source reg along with the FrameIndex of the loaded stack slot.  If
     59 /// not, return 0.  This predicate must return 0 if the instruction has
     60 /// any side effects other than storing to the stack slot.
     61 unsigned BlackfinInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
     62                                                int &FrameIndex) const {
     63   switch (MI->getOpcode()) {
     64   default: break;
     65   case BF::STORE32fi:
     66   case BF::STORE16fi:
     67     if (MI->getOperand(1).isFI() &&
     68         MI->getOperand(2).isImm() &&
     69         MI->getOperand(2).getImm() == 0) {
     70       FrameIndex = MI->getOperand(1).getIndex();
     71       return MI->getOperand(0).getReg();
     72     }
     73     break;
     74   }
     75   return 0;
     76 }
     77 
     78 unsigned BlackfinInstrInfo::
     79 InsertBranch(MachineBasicBlock &MBB,
     80              MachineBasicBlock *TBB,
     81              MachineBasicBlock *FBB,
     82              const SmallVectorImpl<MachineOperand> &Cond,
     83              DebugLoc DL) const {
     84   // Shouldn't be a fall through.
     85   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
     86   assert((Cond.size() == 1 || Cond.size() == 0) &&
     87          "Branch conditions have one component!");
     88 
     89   if (Cond.empty()) {
     90     // Unconditional branch?
     91     assert(!FBB && "Unconditional branch with multiple successors!");
     92     BuildMI(&MBB, DL, get(BF::JUMPa)).addMBB(TBB);
     93     return 1;
     94   }
     95 
     96   // Conditional branch.
     97   llvm_unreachable("Implement conditional branches!");
     98 }
     99 
    100 void BlackfinInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
    101                                     MachineBasicBlock::iterator I, DebugLoc DL,
    102                                     unsigned DestReg, unsigned SrcReg,
    103                                     bool KillSrc) const {
    104   if (BF::ALLRegClass.contains(DestReg, SrcReg)) {
    105     BuildMI(MBB, I, DL, get(BF::MOVE), DestReg)
    106       .addReg(SrcReg, getKillRegState(KillSrc));
    107     return;
    108   }
    109 
    110   if (BF::D16RegClass.contains(DestReg, SrcReg)) {
    111     BuildMI(MBB, I, DL, get(BF::SLL16i), DestReg)
    112       .addReg(SrcReg, getKillRegState(KillSrc))
    113       .addImm(0);
    114     return;
    115   }
    116 
    117   if (BF::DRegClass.contains(DestReg)) {
    118     if (SrcReg == BF::NCC) {
    119       BuildMI(MBB, I, DL, get(BF::MOVENCC_z), DestReg)
    120         .addReg(SrcReg, getKillRegState(KillSrc));
    121       BuildMI(MBB, I, DL, get(BF::BITTGL), DestReg).addReg(DestReg).addImm(0);
    122       return;
    123     }
    124     if (SrcReg == BF::CC) {
    125       BuildMI(MBB, I, DL, get(BF::MOVECC_zext), DestReg)
    126         .addReg(SrcReg, getKillRegState(KillSrc));
    127       return;
    128     }
    129   }
    130 
    131   if (BF::DRegClass.contains(SrcReg)) {
    132     if (DestReg == BF::NCC) {
    133       BuildMI(MBB, I, DL, get(BF::SETEQri_not), DestReg)
    134         .addReg(SrcReg, getKillRegState(KillSrc)).addImm(0);
    135       return;
    136     }
    137     if (DestReg == BF::CC) {
    138       BuildMI(MBB, I, DL, get(BF::MOVECC_nz), DestReg)
    139         .addReg(SrcReg, getKillRegState(KillSrc));
    140       return;
    141     }
    142   }
    143 
    144 
    145   if (DestReg == BF::NCC && SrcReg == BF::CC) {
    146     BuildMI(MBB, I, DL, get(BF::MOVE_ncccc), DestReg)
    147       .addReg(SrcReg, getKillRegState(KillSrc));
    148     return;
    149   }
    150 
    151   if (DestReg == BF::CC && SrcReg == BF::NCC) {
    152     BuildMI(MBB, I, DL, get(BF::MOVE_ccncc), DestReg)
    153       .addReg(SrcReg, getKillRegState(KillSrc));
    154     return;
    155   }
    156 
    157   llvm_unreachable("Bad reg-to-reg copy");
    158 }
    159 
    160 static bool inClass(const TargetRegisterClass &Test,
    161                     unsigned Reg,
    162                     const TargetRegisterClass *RC) {
    163   if (TargetRegisterInfo::isPhysicalRegister(Reg))
    164     return Test.contains(Reg);
    165   else
    166     return Test.hasSubClassEq(RC);
    167 }
    168 
    169 void
    170 BlackfinInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
    171                                        MachineBasicBlock::iterator I,
    172                                        unsigned SrcReg,
    173                                        bool isKill,
    174                                        int FI,
    175                                        const TargetRegisterClass *RC,
    176                                        const TargetRegisterInfo *TRI) const {
    177   DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
    178 
    179   if (inClass(BF::DPRegClass, SrcReg, RC)) {
    180     BuildMI(MBB, I, DL, get(BF::STORE32fi))
    181       .addReg(SrcReg, getKillRegState(isKill))
    182       .addFrameIndex(FI)
    183       .addImm(0);
    184     return;
    185   }
    186 
    187   if (inClass(BF::D16RegClass, SrcReg, RC)) {
    188     BuildMI(MBB, I, DL, get(BF::STORE16fi))
    189       .addReg(SrcReg, getKillRegState(isKill))
    190       .addFrameIndex(FI)
    191       .addImm(0);
    192     return;
    193   }
    194 
    195   if (inClass(BF::AnyCCRegClass, SrcReg, RC)) {
    196     BuildMI(MBB, I, DL, get(BF::STORE8fi))
    197       .addReg(SrcReg, getKillRegState(isKill))
    198       .addFrameIndex(FI)
    199       .addImm(0);
    200     return;
    201   }
    202 
    203   llvm_unreachable((std::string("Cannot store regclass to stack slot: ")+
    204                     RC->getName()).c_str());
    205 }
    206 
    207 void BlackfinInstrInfo::
    208 storeRegToAddr(MachineFunction &MF,
    209                unsigned SrcReg,
    210                bool isKill,
    211                SmallVectorImpl<MachineOperand> &Addr,
    212                const TargetRegisterClass *RC,
    213                SmallVectorImpl<MachineInstr*> &NewMIs) const {
    214   llvm_unreachable("storeRegToAddr not implemented");
    215 }
    216 
    217 void
    218 BlackfinInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
    219                                         MachineBasicBlock::iterator I,
    220                                         unsigned DestReg,
    221                                         int FI,
    222                                         const TargetRegisterClass *RC,
    223                                         const TargetRegisterInfo *TRI) const {
    224   DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
    225   if (inClass(BF::DPRegClass, DestReg, RC)) {
    226     BuildMI(MBB, I, DL, get(BF::LOAD32fi), DestReg)
    227       .addFrameIndex(FI)
    228       .addImm(0);
    229     return;
    230   }
    231 
    232   if (inClass(BF::D16RegClass, DestReg, RC)) {
    233     BuildMI(MBB, I, DL, get(BF::LOAD16fi), DestReg)
    234       .addFrameIndex(FI)
    235       .addImm(0);
    236     return;
    237   }
    238 
    239   if (inClass(BF::AnyCCRegClass, DestReg, RC)) {
    240     BuildMI(MBB, I, DL, get(BF::LOAD8fi), DestReg)
    241       .addFrameIndex(FI)
    242       .addImm(0);
    243     return;
    244   }
    245 
    246   llvm_unreachable("Cannot load regclass from stack slot");
    247 }
    248 
    249 void BlackfinInstrInfo::
    250 loadRegFromAddr(MachineFunction &MF,
    251                 unsigned DestReg,
    252                 SmallVectorImpl<MachineOperand> &Addr,
    253                 const TargetRegisterClass *RC,
    254                 SmallVectorImpl<MachineInstr*> &NewMIs) const {
    255   llvm_unreachable("loadRegFromAddr not implemented");
    256 }
    257