Home | History | Annotate | Download | only in R600
      1 //===-- SIInstrInfo.cpp - SI 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 /// \file
     11 /// \brief SI Implementation of TargetInstrInfo.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 
     16 #include "SIInstrInfo.h"
     17 #include "AMDGPUTargetMachine.h"
     18 #include "llvm/CodeGen/MachineInstrBuilder.h"
     19 #include "llvm/CodeGen/MachineRegisterInfo.h"
     20 #include "llvm/MC/MCInstrDesc.h"
     21 #include <stdio.h>
     22 
     23 using namespace llvm;
     24 
     25 SIInstrInfo::SIInstrInfo(AMDGPUTargetMachine &tm)
     26   : AMDGPUInstrInfo(tm),
     27     RI(tm)
     28     { }
     29 
     30 const SIRegisterInfo &SIInstrInfo::getRegisterInfo() const {
     31   return RI;
     32 }
     33 
     34 void
     35 SIInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
     36                          MachineBasicBlock::iterator MI, DebugLoc DL,
     37                          unsigned DestReg, unsigned SrcReg,
     38                          bool KillSrc) const {
     39 
     40   // If we are trying to copy to or from SCC, there is a bug somewhere else in
     41   // the backend.  While it may be theoretically possible to do this, it should
     42   // never be necessary.
     43   assert(DestReg != AMDGPU::SCC && SrcReg != AMDGPU::SCC);
     44 
     45   static const int16_t Sub0_15[] = {
     46     AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3,
     47     AMDGPU::sub4, AMDGPU::sub5, AMDGPU::sub6, AMDGPU::sub7,
     48     AMDGPU::sub8, AMDGPU::sub9, AMDGPU::sub10, AMDGPU::sub11,
     49     AMDGPU::sub12, AMDGPU::sub13, AMDGPU::sub14, AMDGPU::sub15, 0
     50   };
     51 
     52   static const int16_t Sub0_7[] = {
     53     AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3,
     54     AMDGPU::sub4, AMDGPU::sub5, AMDGPU::sub6, AMDGPU::sub7, 0
     55   };
     56 
     57   static const int16_t Sub0_3[] = {
     58     AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, AMDGPU::sub3, 0
     59   };
     60 
     61   static const int16_t Sub0_2[] = {
     62     AMDGPU::sub0, AMDGPU::sub1, AMDGPU::sub2, 0
     63   };
     64 
     65   static const int16_t Sub0_1[] = {
     66     AMDGPU::sub0, AMDGPU::sub1, 0
     67   };
     68 
     69   unsigned Opcode;
     70   const int16_t *SubIndices;
     71 
     72   if (AMDGPU::M0 == DestReg) {
     73     // Check if M0 isn't already set to this value
     74     for (MachineBasicBlock::reverse_iterator E = MBB.rend(),
     75       I = MachineBasicBlock::reverse_iterator(MI); I != E; ++I) {
     76 
     77       if (!I->definesRegister(AMDGPU::M0))
     78         continue;
     79 
     80       unsigned Opc = I->getOpcode();
     81       if (Opc != TargetOpcode::COPY && Opc != AMDGPU::S_MOV_B32)
     82         break;
     83 
     84       if (!I->readsRegister(SrcReg))
     85         break;
     86 
     87       // The copy isn't necessary
     88       return;
     89     }
     90   }
     91 
     92   if (AMDGPU::SReg_32RegClass.contains(DestReg)) {
     93     assert(AMDGPU::SReg_32RegClass.contains(SrcReg));
     94     BuildMI(MBB, MI, DL, get(AMDGPU::S_MOV_B32), DestReg)
     95             .addReg(SrcReg, getKillRegState(KillSrc));
     96     return;
     97 
     98   } else if (AMDGPU::SReg_64RegClass.contains(DestReg)) {
     99     assert(AMDGPU::SReg_64RegClass.contains(SrcReg));
    100     BuildMI(MBB, MI, DL, get(AMDGPU::S_MOV_B64), DestReg)
    101             .addReg(SrcReg, getKillRegState(KillSrc));
    102     return;
    103 
    104   } else if (AMDGPU::SReg_128RegClass.contains(DestReg)) {
    105     assert(AMDGPU::SReg_128RegClass.contains(SrcReg));
    106     Opcode = AMDGPU::S_MOV_B32;
    107     SubIndices = Sub0_3;
    108 
    109   } else if (AMDGPU::SReg_256RegClass.contains(DestReg)) {
    110     assert(AMDGPU::SReg_256RegClass.contains(SrcReg));
    111     Opcode = AMDGPU::S_MOV_B32;
    112     SubIndices = Sub0_7;
    113 
    114   } else if (AMDGPU::SReg_512RegClass.contains(DestReg)) {
    115     assert(AMDGPU::SReg_512RegClass.contains(SrcReg));
    116     Opcode = AMDGPU::S_MOV_B32;
    117     SubIndices = Sub0_15;
    118 
    119   } else if (AMDGPU::VReg_32RegClass.contains(DestReg)) {
    120     assert(AMDGPU::VReg_32RegClass.contains(SrcReg) ||
    121 	   AMDGPU::SReg_32RegClass.contains(SrcReg));
    122     BuildMI(MBB, MI, DL, get(AMDGPU::V_MOV_B32_e32), DestReg)
    123             .addReg(SrcReg, getKillRegState(KillSrc));
    124     return;
    125 
    126   } else if (AMDGPU::VReg_64RegClass.contains(DestReg)) {
    127     assert(AMDGPU::VReg_64RegClass.contains(SrcReg) ||
    128 	   AMDGPU::SReg_64RegClass.contains(SrcReg));
    129     Opcode = AMDGPU::V_MOV_B32_e32;
    130     SubIndices = Sub0_1;
    131 
    132   } else if (AMDGPU::VReg_96RegClass.contains(DestReg)) {
    133     assert(AMDGPU::VReg_96RegClass.contains(SrcReg));
    134     Opcode = AMDGPU::V_MOV_B32_e32;
    135     SubIndices = Sub0_2;
    136 
    137   } else if (AMDGPU::VReg_128RegClass.contains(DestReg)) {
    138     assert(AMDGPU::VReg_128RegClass.contains(SrcReg) ||
    139 	   AMDGPU::SReg_128RegClass.contains(SrcReg));
    140     Opcode = AMDGPU::V_MOV_B32_e32;
    141     SubIndices = Sub0_3;
    142 
    143   } else if (AMDGPU::VReg_256RegClass.contains(DestReg)) {
    144     assert(AMDGPU::VReg_256RegClass.contains(SrcReg) ||
    145 	   AMDGPU::SReg_256RegClass.contains(SrcReg));
    146     Opcode = AMDGPU::V_MOV_B32_e32;
    147     SubIndices = Sub0_7;
    148 
    149   } else if (AMDGPU::VReg_512RegClass.contains(DestReg)) {
    150     assert(AMDGPU::VReg_512RegClass.contains(SrcReg) ||
    151 	   AMDGPU::SReg_512RegClass.contains(SrcReg));
    152     Opcode = AMDGPU::V_MOV_B32_e32;
    153     SubIndices = Sub0_15;
    154 
    155   } else {
    156     llvm_unreachable("Can't copy register!");
    157   }
    158 
    159   while (unsigned SubIdx = *SubIndices++) {
    160     MachineInstrBuilder Builder = BuildMI(MBB, MI, DL,
    161       get(Opcode), RI.getSubReg(DestReg, SubIdx));
    162 
    163     Builder.addReg(RI.getSubReg(SrcReg, SubIdx), getKillRegState(KillSrc));
    164 
    165     if (*SubIndices)
    166       Builder.addReg(DestReg, RegState::Define | RegState::Implicit);
    167   }
    168 }
    169 
    170 unsigned SIInstrInfo::commuteOpcode(unsigned Opcode) const {
    171 
    172   int NewOpc;
    173 
    174   // Try to map original to commuted opcode
    175   if ((NewOpc = AMDGPU::getCommuteRev(Opcode)) != -1)
    176     return NewOpc;
    177 
    178   // Try to map commuted to original opcode
    179   if ((NewOpc = AMDGPU::getCommuteOrig(Opcode)) != -1)
    180     return NewOpc;
    181 
    182   return Opcode;
    183 }
    184 
    185 MachineInstr *SIInstrInfo::commuteInstruction(MachineInstr *MI,
    186                                               bool NewMI) const {
    187 
    188   if (MI->getNumOperands() < 3 || !MI->getOperand(1).isReg() ||
    189       !MI->getOperand(2).isReg())
    190     return 0;
    191 
    192   MI = TargetInstrInfo::commuteInstruction(MI, NewMI);
    193 
    194   if (MI)
    195     MI->setDesc(get(commuteOpcode(MI->getOpcode())));
    196 
    197   return MI;
    198 }
    199 
    200 MachineInstr * SIInstrInfo::getMovImmInstr(MachineFunction *MF, unsigned DstReg,
    201                                            int64_t Imm) const {
    202   MachineInstr * MI = MF->CreateMachineInstr(get(AMDGPU::V_MOV_B32_e32), DebugLoc());
    203   MachineInstrBuilder MIB(*MF, MI);
    204   MIB.addReg(DstReg, RegState::Define);
    205   MIB.addImm(Imm);
    206 
    207   return MI;
    208 
    209 }
    210 
    211 bool SIInstrInfo::isMov(unsigned Opcode) const {
    212   switch(Opcode) {
    213   default: return false;
    214   case AMDGPU::S_MOV_B32:
    215   case AMDGPU::S_MOV_B64:
    216   case AMDGPU::V_MOV_B32_e32:
    217   case AMDGPU::V_MOV_B32_e64:
    218     return true;
    219   }
    220 }
    221 
    222 bool
    223 SIInstrInfo::isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const {
    224   return RC != &AMDGPU::EXECRegRegClass;
    225 }
    226 
    227 //===----------------------------------------------------------------------===//
    228 // Indirect addressing callbacks
    229 //===----------------------------------------------------------------------===//
    230 
    231 unsigned SIInstrInfo::calculateIndirectAddress(unsigned RegIndex,
    232                                                  unsigned Channel) const {
    233   assert(Channel == 0);
    234   return RegIndex;
    235 }
    236 
    237 
    238 int SIInstrInfo::getIndirectIndexBegin(const MachineFunction &MF) const {
    239   llvm_unreachable("Unimplemented");
    240 }
    241 
    242 int SIInstrInfo::getIndirectIndexEnd(const MachineFunction &MF) const {
    243   llvm_unreachable("Unimplemented");
    244 }
    245 
    246 const TargetRegisterClass *SIInstrInfo::getIndirectAddrStoreRegClass(
    247                                                      unsigned SourceReg) const {
    248   llvm_unreachable("Unimplemented");
    249 }
    250 
    251 const TargetRegisterClass *SIInstrInfo::getIndirectAddrLoadRegClass() const {
    252   llvm_unreachable("Unimplemented");
    253 }
    254 
    255 MachineInstrBuilder SIInstrInfo::buildIndirectWrite(
    256                                    MachineBasicBlock *MBB,
    257                                    MachineBasicBlock::iterator I,
    258                                    unsigned ValueReg,
    259                                    unsigned Address, unsigned OffsetReg) const {
    260   llvm_unreachable("Unimplemented");
    261 }
    262 
    263 MachineInstrBuilder SIInstrInfo::buildIndirectRead(
    264                                    MachineBasicBlock *MBB,
    265                                    MachineBasicBlock::iterator I,
    266                                    unsigned ValueReg,
    267                                    unsigned Address, unsigned OffsetReg) const {
    268   llvm_unreachable("Unimplemented");
    269 }
    270 
    271 const TargetRegisterClass *SIInstrInfo::getSuperIndirectRegClass() const {
    272   llvm_unreachable("Unimplemented");
    273 }
    274