Home | History | Annotate | Download | only in SystemZ
      1 //===- SystemZInstrInfo.cpp - SystemZ Instruction Information --------------===//
      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 SystemZ implementation of the TargetInstrInfo class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "SystemZ.h"
     15 #include "SystemZInstrBuilder.h"
     16 #include "SystemZInstrInfo.h"
     17 #include "SystemZMachineFunctionInfo.h"
     18 #include "SystemZTargetMachine.h"
     19 #include "llvm/Function.h"
     20 #include "llvm/CodeGen/MachineFrameInfo.h"
     21 #include "llvm/CodeGen/MachineInstrBuilder.h"
     22 #include "llvm/CodeGen/MachineRegisterInfo.h"
     23 #include "llvm/CodeGen/PseudoSourceValue.h"
     24 #include "llvm/Support/ErrorHandling.h"
     25 #include "llvm/Support/TargetRegistry.h"
     26 
     27 #define GET_INSTRINFO_CTOR
     28 #include "SystemZGenInstrInfo.inc"
     29 
     30 using namespace llvm;
     31 
     32 SystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine &tm)
     33   : SystemZGenInstrInfo(SystemZ::ADJCALLSTACKUP, SystemZ::ADJCALLSTACKDOWN),
     34     RI(tm, *this), TM(tm) {
     35 }
     36 
     37 /// isGVStub - Return true if the GV requires an extra load to get the
     38 /// real address.
     39 static inline bool isGVStub(GlobalValue *GV, SystemZTargetMachine &TM) {
     40   return TM.getSubtarget<SystemZSubtarget>().GVRequiresExtraLoad(GV, TM, false);
     41 }
     42 
     43 void SystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
     44                                           MachineBasicBlock::iterator MI,
     45                                     unsigned SrcReg, bool isKill, int FrameIdx,
     46                                            const TargetRegisterClass *RC,
     47                                            const TargetRegisterInfo *TRI) const {
     48   DebugLoc DL;
     49   if (MI != MBB.end()) DL = MI->getDebugLoc();
     50 
     51   unsigned Opc = 0;
     52   if (RC == &SystemZ::GR32RegClass ||
     53       RC == &SystemZ::ADDR32RegClass)
     54     Opc = SystemZ::MOV32mr;
     55   else if (RC == &SystemZ::GR64RegClass ||
     56            RC == &SystemZ::ADDR64RegClass) {
     57     Opc = SystemZ::MOV64mr;
     58   } else if (RC == &SystemZ::FP32RegClass) {
     59     Opc = SystemZ::FMOV32mr;
     60   } else if (RC == &SystemZ::FP64RegClass) {
     61     Opc = SystemZ::FMOV64mr;
     62   } else if (RC == &SystemZ::GR64PRegClass) {
     63     Opc = SystemZ::MOV64Pmr;
     64   } else if (RC == &SystemZ::GR128RegClass) {
     65     Opc = SystemZ::MOV128mr;
     66   } else
     67     llvm_unreachable("Unsupported regclass to store");
     68 
     69   addFrameReference(BuildMI(MBB, MI, DL, get(Opc)), FrameIdx)
     70     .addReg(SrcReg, getKillRegState(isKill));
     71 }
     72 
     73 void SystemZInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
     74                                            MachineBasicBlock::iterator MI,
     75                                            unsigned DestReg, int FrameIdx,
     76                                             const TargetRegisterClass *RC,
     77                                             const TargetRegisterInfo *TRI) const{
     78   DebugLoc DL;
     79   if (MI != MBB.end()) DL = MI->getDebugLoc();
     80 
     81   unsigned Opc = 0;
     82   if (RC == &SystemZ::GR32RegClass ||
     83       RC == &SystemZ::ADDR32RegClass)
     84     Opc = SystemZ::MOV32rm;
     85   else if (RC == &SystemZ::GR64RegClass ||
     86            RC == &SystemZ::ADDR64RegClass) {
     87     Opc = SystemZ::MOV64rm;
     88   } else if (RC == &SystemZ::FP32RegClass) {
     89     Opc = SystemZ::FMOV32rm;
     90   } else if (RC == &SystemZ::FP64RegClass) {
     91     Opc = SystemZ::FMOV64rm;
     92   } else if (RC == &SystemZ::GR64PRegClass) {
     93     Opc = SystemZ::MOV64Prm;
     94   } else if (RC == &SystemZ::GR128RegClass) {
     95     Opc = SystemZ::MOV128rm;
     96   } else
     97     llvm_unreachable("Unsupported regclass to load");
     98 
     99   addFrameReference(BuildMI(MBB, MI, DL, get(Opc), DestReg), FrameIdx);
    100 }
    101 
    102 void SystemZInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
    103                                    MachineBasicBlock::iterator I, DebugLoc DL,
    104                                    unsigned DestReg, unsigned SrcReg,
    105                                    bool KillSrc) const {
    106   unsigned Opc;
    107   if (SystemZ::GR64RegClass.contains(DestReg, SrcReg))
    108     Opc = SystemZ::MOV64rr;
    109   else if (SystemZ::GR32RegClass.contains(DestReg, SrcReg))
    110     Opc = SystemZ::MOV32rr;
    111   else if (SystemZ::GR64PRegClass.contains(DestReg, SrcReg))
    112     Opc = SystemZ::MOV64rrP;
    113   else if (SystemZ::GR128RegClass.contains(DestReg, SrcReg))
    114     Opc = SystemZ::MOV128rr;
    115   else if (SystemZ::FP32RegClass.contains(DestReg, SrcReg))
    116     Opc = SystemZ::FMOV32rr;
    117   else if (SystemZ::FP64RegClass.contains(DestReg, SrcReg))
    118     Opc = SystemZ::FMOV64rr;
    119   else
    120     llvm_unreachable("Impossible reg-to-reg copy");
    121 
    122   BuildMI(MBB, I, DL, get(Opc), DestReg)
    123     .addReg(SrcReg, getKillRegState(KillSrc));
    124 }
    125 
    126 unsigned SystemZInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
    127                                                int &FrameIndex) const {
    128   switch (MI->getOpcode()) {
    129   default: break;
    130   case SystemZ::MOV32rm:
    131   case SystemZ::MOV32rmy:
    132   case SystemZ::MOV64rm:
    133   case SystemZ::MOVSX32rm8:
    134   case SystemZ::MOVSX32rm16y:
    135   case SystemZ::MOVSX64rm8:
    136   case SystemZ::MOVSX64rm16:
    137   case SystemZ::MOVSX64rm32:
    138   case SystemZ::MOVZX32rm8:
    139   case SystemZ::MOVZX32rm16:
    140   case SystemZ::MOVZX64rm8:
    141   case SystemZ::MOVZX64rm16:
    142   case SystemZ::MOVZX64rm32:
    143   case SystemZ::FMOV32rm:
    144   case SystemZ::FMOV32rmy:
    145   case SystemZ::FMOV64rm:
    146   case SystemZ::FMOV64rmy:
    147   case SystemZ::MOV64Prm:
    148   case SystemZ::MOV64Prmy:
    149   case SystemZ::MOV128rm:
    150     if (MI->getOperand(1).isFI() &&
    151         MI->getOperand(2).isImm() && MI->getOperand(3).isReg() &&
    152         MI->getOperand(2).getImm() == 0 && MI->getOperand(3).getReg() == 0) {
    153       FrameIndex = MI->getOperand(1).getIndex();
    154       return MI->getOperand(0).getReg();
    155     }
    156     break;
    157   }
    158   return 0;
    159 }
    160 
    161 unsigned SystemZInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
    162                                               int &FrameIndex) const {
    163   switch (MI->getOpcode()) {
    164   default: break;
    165   case SystemZ::MOV32mr:
    166   case SystemZ::MOV32mry:
    167   case SystemZ::MOV64mr:
    168   case SystemZ::MOV32m8r:
    169   case SystemZ::MOV32m8ry:
    170   case SystemZ::MOV32m16r:
    171   case SystemZ::MOV32m16ry:
    172   case SystemZ::MOV64m8r:
    173   case SystemZ::MOV64m8ry:
    174   case SystemZ::MOV64m16r:
    175   case SystemZ::MOV64m16ry:
    176   case SystemZ::MOV64m32r:
    177   case SystemZ::MOV64m32ry:
    178   case SystemZ::FMOV32mr:
    179   case SystemZ::FMOV32mry:
    180   case SystemZ::FMOV64mr:
    181   case SystemZ::FMOV64mry:
    182   case SystemZ::MOV64Pmr:
    183   case SystemZ::MOV64Pmry:
    184   case SystemZ::MOV128mr:
    185     if (MI->getOperand(0).isFI() &&
    186         MI->getOperand(1).isImm() && MI->getOperand(2).isReg() &&
    187         MI->getOperand(1).getImm() == 0 && MI->getOperand(2).getReg() == 0) {
    188       FrameIndex = MI->getOperand(0).getIndex();
    189       return MI->getOperand(3).getReg();
    190     }
    191     break;
    192   }
    193   return 0;
    194 }
    195 
    196 bool SystemZInstrInfo::
    197 ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
    198   assert(Cond.size() == 1 && "Invalid Xbranch condition!");
    199 
    200   SystemZCC::CondCodes CC = static_cast<SystemZCC::CondCodes>(Cond[0].getImm());
    201   Cond[0].setImm(getOppositeCondition(CC));
    202   return false;
    203 }
    204 
    205 bool SystemZInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
    206   const MCInstrDesc &MCID = MI->getDesc();
    207   if (!MCID.isTerminator()) return false;
    208 
    209   // Conditional branch is a special case.
    210   if (MCID.isBranch() && !MCID.isBarrier())
    211     return true;
    212   if (!MCID.isPredicable())
    213     return true;
    214   return !isPredicated(MI);
    215 }
    216 
    217 bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
    218                                      MachineBasicBlock *&TBB,
    219                                      MachineBasicBlock *&FBB,
    220                                      SmallVectorImpl<MachineOperand> &Cond,
    221                                      bool AllowModify) const {
    222   // Start from the bottom of the block and work up, examining the
    223   // terminator instructions.
    224   MachineBasicBlock::iterator I = MBB.end();
    225   while (I != MBB.begin()) {
    226     --I;
    227     if (I->isDebugValue())
    228       continue;
    229     // Working from the bottom, when we see a non-terminator
    230     // instruction, we're done.
    231     if (!isUnpredicatedTerminator(I))
    232       break;
    233 
    234     // A terminator that isn't a branch can't easily be handled
    235     // by this analysis.
    236     if (!I->getDesc().isBranch())
    237       return true;
    238 
    239     // Handle unconditional branches.
    240     if (I->getOpcode() == SystemZ::JMP) {
    241       if (!AllowModify) {
    242         TBB = I->getOperand(0).getMBB();
    243         continue;
    244       }
    245 
    246       // If the block has any instructions after a JMP, delete them.
    247       while (llvm::next(I) != MBB.end())
    248         llvm::next(I)->eraseFromParent();
    249       Cond.clear();
    250       FBB = 0;
    251 
    252       // Delete the JMP if it's equivalent to a fall-through.
    253       if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
    254         TBB = 0;
    255         I->eraseFromParent();
    256         I = MBB.end();
    257         continue;
    258       }
    259 
    260       // TBB is used to indicate the unconditinal destination.
    261       TBB = I->getOperand(0).getMBB();
    262       continue;
    263     }
    264 
    265     // Handle conditional branches.
    266     SystemZCC::CondCodes BranchCode = getCondFromBranchOpc(I->getOpcode());
    267     if (BranchCode == SystemZCC::INVALID)
    268       return true;  // Can't handle indirect branch.
    269 
    270     // Working from the bottom, handle the first conditional branch.
    271     if (Cond.empty()) {
    272       FBB = TBB;
    273       TBB = I->getOperand(0).getMBB();
    274       Cond.push_back(MachineOperand::CreateImm(BranchCode));
    275       continue;
    276     }
    277 
    278     // Handle subsequent conditional branches. Only handle the case where all
    279     // conditional branches branch to the same destination.
    280     assert(Cond.size() == 1);
    281     assert(TBB);
    282 
    283     // Only handle the case where all conditional branches branch to
    284     // the same destination.
    285     if (TBB != I->getOperand(0).getMBB())
    286       return true;
    287 
    288     SystemZCC::CondCodes OldBranchCode = (SystemZCC::CondCodes)Cond[0].getImm();
    289     // If the conditions are the same, we can leave them alone.
    290     if (OldBranchCode == BranchCode)
    291       continue;
    292 
    293     return true;
    294   }
    295 
    296   return false;
    297 }
    298 
    299 unsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
    300   MachineBasicBlock::iterator I = MBB.end();
    301   unsigned Count = 0;
    302 
    303   while (I != MBB.begin()) {
    304     --I;
    305     if (I->isDebugValue())
    306       continue;
    307     if (I->getOpcode() != SystemZ::JMP &&
    308         getCondFromBranchOpc(I->getOpcode()) == SystemZCC::INVALID)
    309       break;
    310     // Remove the branch.
    311     I->eraseFromParent();
    312     I = MBB.end();
    313     ++Count;
    314   }
    315 
    316   return Count;
    317 }
    318 
    319 unsigned
    320 SystemZInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
    321                                MachineBasicBlock *FBB,
    322                                const SmallVectorImpl<MachineOperand> &Cond,
    323                                DebugLoc DL) const {
    324   // Shouldn't be a fall through.
    325   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
    326   assert((Cond.size() == 1 || Cond.size() == 0) &&
    327          "SystemZ branch conditions have one component!");
    328 
    329   if (Cond.empty()) {
    330     // Unconditional branch?
    331     assert(!FBB && "Unconditional branch with multiple successors!");
    332     BuildMI(&MBB, DL, get(SystemZ::JMP)).addMBB(TBB);
    333     return 1;
    334   }
    335 
    336   // Conditional branch.
    337   unsigned Count = 0;
    338   SystemZCC::CondCodes CC = (SystemZCC::CondCodes)Cond[0].getImm();
    339   BuildMI(&MBB, DL, getBrCond(CC)).addMBB(TBB);
    340   ++Count;
    341 
    342   if (FBB) {
    343     // Two-way Conditional branch. Insert the second branch.
    344     BuildMI(&MBB, DL, get(SystemZ::JMP)).addMBB(FBB);
    345     ++Count;
    346   }
    347   return Count;
    348 }
    349 
    350 const MCInstrDesc&
    351 SystemZInstrInfo::getBrCond(SystemZCC::CondCodes CC) const {
    352   switch (CC) {
    353   default:
    354    llvm_unreachable("Unknown condition code!");
    355   case SystemZCC::O:   return get(SystemZ::JO);
    356   case SystemZCC::H:   return get(SystemZ::JH);
    357   case SystemZCC::NLE: return get(SystemZ::JNLE);
    358   case SystemZCC::L:   return get(SystemZ::JL);
    359   case SystemZCC::NHE: return get(SystemZ::JNHE);
    360   case SystemZCC::LH:  return get(SystemZ::JLH);
    361   case SystemZCC::NE:  return get(SystemZ::JNE);
    362   case SystemZCC::E:   return get(SystemZ::JE);
    363   case SystemZCC::NLH: return get(SystemZ::JNLH);
    364   case SystemZCC::HE:  return get(SystemZ::JHE);
    365   case SystemZCC::NL:  return get(SystemZ::JNL);
    366   case SystemZCC::LE:  return get(SystemZ::JLE);
    367   case SystemZCC::NH:  return get(SystemZ::JNH);
    368   case SystemZCC::NO:  return get(SystemZ::JNO);
    369   }
    370 }
    371 
    372 SystemZCC::CondCodes
    373 SystemZInstrInfo::getCondFromBranchOpc(unsigned Opc) const {
    374   switch (Opc) {
    375   default:            return SystemZCC::INVALID;
    376   case SystemZ::JO:   return SystemZCC::O;
    377   case SystemZ::JH:   return SystemZCC::H;
    378   case SystemZ::JNLE: return SystemZCC::NLE;
    379   case SystemZ::JL:   return SystemZCC::L;
    380   case SystemZ::JNHE: return SystemZCC::NHE;
    381   case SystemZ::JLH:  return SystemZCC::LH;
    382   case SystemZ::JNE:  return SystemZCC::NE;
    383   case SystemZ::JE:   return SystemZCC::E;
    384   case SystemZ::JNLH: return SystemZCC::NLH;
    385   case SystemZ::JHE:  return SystemZCC::HE;
    386   case SystemZ::JNL:  return SystemZCC::NL;
    387   case SystemZ::JLE:  return SystemZCC::LE;
    388   case SystemZ::JNH:  return SystemZCC::NH;
    389   case SystemZ::JNO:  return SystemZCC::NO;
    390   }
    391 }
    392 
    393 SystemZCC::CondCodes
    394 SystemZInstrInfo::getOppositeCondition(SystemZCC::CondCodes CC) const {
    395   switch (CC) {
    396   default:
    397     llvm_unreachable("Invalid condition!");
    398   case SystemZCC::O:   return SystemZCC::NO;
    399   case SystemZCC::H:   return SystemZCC::NH;
    400   case SystemZCC::NLE: return SystemZCC::LE;
    401   case SystemZCC::L:   return SystemZCC::NL;
    402   case SystemZCC::NHE: return SystemZCC::HE;
    403   case SystemZCC::LH:  return SystemZCC::NLH;
    404   case SystemZCC::NE:  return SystemZCC::E;
    405   case SystemZCC::E:   return SystemZCC::NE;
    406   case SystemZCC::NLH: return SystemZCC::LH;
    407   case SystemZCC::HE:  return SystemZCC::NHE;
    408   case SystemZCC::NL:  return SystemZCC::L;
    409   case SystemZCC::LE:  return SystemZCC::NLE;
    410   case SystemZCC::NH:  return SystemZCC::H;
    411   case SystemZCC::NO:  return SystemZCC::O;
    412   }
    413 }
    414 
    415 const MCInstrDesc&
    416 SystemZInstrInfo::getLongDispOpc(unsigned Opc) const {
    417   switch (Opc) {
    418   default:
    419     llvm_unreachable("Don't have long disp version of this instruction");
    420   case SystemZ::MOV32mr:   return get(SystemZ::MOV32mry);
    421   case SystemZ::MOV32rm:   return get(SystemZ::MOV32rmy);
    422   case SystemZ::MOVSX32rm16: return get(SystemZ::MOVSX32rm16y);
    423   case SystemZ::MOV32m8r:  return get(SystemZ::MOV32m8ry);
    424   case SystemZ::MOV32m16r: return get(SystemZ::MOV32m16ry);
    425   case SystemZ::MOV64m8r:  return get(SystemZ::MOV64m8ry);
    426   case SystemZ::MOV64m16r: return get(SystemZ::MOV64m16ry);
    427   case SystemZ::MOV64m32r: return get(SystemZ::MOV64m32ry);
    428   case SystemZ::MOV8mi:    return get(SystemZ::MOV8miy);
    429   case SystemZ::MUL32rm:   return get(SystemZ::MUL32rmy);
    430   case SystemZ::CMP32rm:   return get(SystemZ::CMP32rmy);
    431   case SystemZ::UCMP32rm:  return get(SystemZ::UCMP32rmy);
    432   case SystemZ::FMOV32mr:  return get(SystemZ::FMOV32mry);
    433   case SystemZ::FMOV64mr:  return get(SystemZ::FMOV64mry);
    434   case SystemZ::FMOV32rm:  return get(SystemZ::FMOV32rmy);
    435   case SystemZ::FMOV64rm:  return get(SystemZ::FMOV64rmy);
    436   case SystemZ::MOV64Pmr:  return get(SystemZ::MOV64Pmry);
    437   case SystemZ::MOV64Prm:  return get(SystemZ::MOV64Prmy);
    438   }
    439 }
    440