Home | History | Annotate | Download | only in Blackfin
      1 //===- BlackfinRegisterInfo.cpp - Blackfin Register 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 TargetRegisterInfo
     11 // class.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "Blackfin.h"
     16 #include "BlackfinRegisterInfo.h"
     17 #include "BlackfinSubtarget.h"
     18 #include "llvm/Support/Debug.h"
     19 #include "llvm/Support/ErrorHandling.h"
     20 #include "llvm/CodeGen/MachineInstrBuilder.h"
     21 #include "llvm/CodeGen/MachineFunction.h"
     22 #include "llvm/CodeGen/MachineFrameInfo.h"
     23 #include "llvm/CodeGen/RegisterScavenging.h"
     24 #include "llvm/Target/TargetFrameLowering.h"
     25 #include "llvm/Target/TargetMachine.h"
     26 #include "llvm/Target/TargetOptions.h"
     27 #include "llvm/Target/TargetInstrInfo.h"
     28 #include "llvm/Type.h"
     29 #include "llvm/ADT/BitVector.h"
     30 #include "llvm/ADT/STLExtras.h"
     31 
     32 #define GET_REGINFO_TARGET_DESC
     33 #include "BlackfinGenRegisterInfo.inc"
     34 
     35 using namespace llvm;
     36 
     37 BlackfinRegisterInfo::BlackfinRegisterInfo(BlackfinSubtarget &st,
     38                                            const TargetInstrInfo &tii)
     39   : BlackfinGenRegisterInfo(BF::RETS), Subtarget(st), TII(tii) {}
     40 
     41 const unsigned*
     42 BlackfinRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
     43   using namespace BF;
     44   static const unsigned CalleeSavedRegs[] = {
     45     FP,
     46     R4, R5, R6, R7,
     47     P3, P4, P5,
     48     0 };
     49   return  CalleeSavedRegs;
     50 }
     51 
     52 BitVector
     53 BlackfinRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
     54   const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
     55 
     56   using namespace BF;
     57   BitVector Reserved(getNumRegs());
     58   Reserved.set(AZ);
     59   Reserved.set(AN);
     60   Reserved.set(AQ);
     61   Reserved.set(AC0);
     62   Reserved.set(AC1);
     63   Reserved.set(AV0);
     64   Reserved.set(AV0S);
     65   Reserved.set(AV1);
     66   Reserved.set(AV1S);
     67   Reserved.set(V);
     68   Reserved.set(VS);
     69   Reserved.set(CYCLES).set(CYCLES2);
     70   Reserved.set(L0);
     71   Reserved.set(L1);
     72   Reserved.set(L2);
     73   Reserved.set(L3);
     74   Reserved.set(SP);
     75   Reserved.set(RETS);
     76   if (TFI->hasFP(MF))
     77     Reserved.set(FP);
     78   return Reserved;
     79 }
     80 
     81 bool BlackfinRegisterInfo::
     82 requiresRegisterScavenging(const MachineFunction &MF) const {
     83   return true;
     84 }
     85 
     86 // Emit instructions to add delta to D/P register. ScratchReg must be of the
     87 // same class as Reg (P).
     88 void BlackfinRegisterInfo::adjustRegister(MachineBasicBlock &MBB,
     89                                           MachineBasicBlock::iterator I,
     90                                           DebugLoc DL,
     91                                           unsigned Reg,
     92                                           unsigned ScratchReg,
     93                                           int delta) const {
     94   if (!delta)
     95     return;
     96   if (isInt<7>(delta)) {
     97     BuildMI(MBB, I, DL, TII.get(BF::ADDpp_imm7), Reg)
     98       .addReg(Reg)              // No kill on two-addr operand
     99       .addImm(delta);
    100     return;
    101   }
    102 
    103   // We must load delta into ScratchReg and add that.
    104   loadConstant(MBB, I, DL, ScratchReg, delta);
    105   if (BF::PRegClass.contains(Reg)) {
    106     assert(BF::PRegClass.contains(ScratchReg) &&
    107            "ScratchReg must be a P register");
    108     BuildMI(MBB, I, DL, TII.get(BF::ADDpp), Reg)
    109       .addReg(Reg, RegState::Kill)
    110       .addReg(ScratchReg, RegState::Kill);
    111   } else {
    112     assert(BF::DRegClass.contains(Reg) && "Reg must be a D or P register");
    113     assert(BF::DRegClass.contains(ScratchReg) &&
    114            "ScratchReg must be a D register");
    115     BuildMI(MBB, I, DL, TII.get(BF::ADD), Reg)
    116       .addReg(Reg, RegState::Kill)
    117       .addReg(ScratchReg, RegState::Kill);
    118   }
    119 }
    120 
    121 // Emit instructions to load a constant into D/P register
    122 void BlackfinRegisterInfo::loadConstant(MachineBasicBlock &MBB,
    123                                         MachineBasicBlock::iterator I,
    124                                         DebugLoc DL,
    125                                         unsigned Reg,
    126                                         int value) const {
    127   if (isInt<7>(value)) {
    128     BuildMI(MBB, I, DL, TII.get(BF::LOADimm7), Reg).addImm(value);
    129     return;
    130   }
    131 
    132   if (isUInt<16>(value)) {
    133     BuildMI(MBB, I, DL, TII.get(BF::LOADuimm16), Reg).addImm(value);
    134     return;
    135   }
    136 
    137   if (isInt<16>(value)) {
    138     BuildMI(MBB, I, DL, TII.get(BF::LOADimm16), Reg).addImm(value);
    139     return;
    140   }
    141 
    142   // We must split into halves
    143   BuildMI(MBB, I, DL,
    144           TII.get(BF::LOAD16i), getSubReg(Reg, BF::hi16))
    145     .addImm((value >> 16) & 0xffff)
    146     .addReg(Reg, RegState::ImplicitDefine);
    147   BuildMI(MBB, I, DL,
    148           TII.get(BF::LOAD16i), getSubReg(Reg, BF::lo16))
    149     .addImm(value & 0xffff)
    150     .addReg(Reg, RegState::ImplicitKill)
    151     .addReg(Reg, RegState::ImplicitDefine);
    152 }
    153 
    154 void BlackfinRegisterInfo::
    155 eliminateCallFramePseudoInstr(MachineFunction &MF,
    156                               MachineBasicBlock &MBB,
    157                               MachineBasicBlock::iterator I) const {
    158   const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
    159 
    160   if (!TFI->hasReservedCallFrame(MF)) {
    161     int64_t Amount = I->getOperand(0).getImm();
    162     if (Amount != 0) {
    163       assert(Amount%4 == 0 && "Unaligned call frame size");
    164       if (I->getOpcode() == BF::ADJCALLSTACKDOWN) {
    165         adjustRegister(MBB, I, I->getDebugLoc(), BF::SP, BF::P1, -Amount);
    166       } else {
    167         assert(I->getOpcode() == BF::ADJCALLSTACKUP &&
    168                "Unknown call frame pseudo instruction");
    169         adjustRegister(MBB, I, I->getDebugLoc(), BF::SP, BF::P1, Amount);
    170       }
    171     }
    172   }
    173   MBB.erase(I);
    174 }
    175 
    176 /// findScratchRegister - Find a 'free' register. Try for a call-clobbered
    177 /// register first and then a spilled callee-saved register if that fails.
    178 static unsigned findScratchRegister(MachineBasicBlock::iterator II,
    179                                     RegScavenger *RS,
    180                                     const TargetRegisterClass *RC,
    181                                     int SPAdj) {
    182   assert(RS && "Register scavenging must be on");
    183   unsigned Reg = RS->FindUnusedReg(RC);
    184   if (Reg == 0)
    185     Reg = RS->scavengeRegister(RC, II, SPAdj);
    186   return Reg;
    187 }
    188 
    189 void
    190 BlackfinRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
    191                                           int SPAdj, RegScavenger *RS) const {
    192   MachineInstr &MI = *II;
    193   MachineBasicBlock &MBB = *MI.getParent();
    194   MachineFunction &MF = *MBB.getParent();
    195   const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
    196   DebugLoc DL = MI.getDebugLoc();
    197 
    198   unsigned FIPos;
    199   for (FIPos=0; !MI.getOperand(FIPos).isFI(); ++FIPos) {
    200     assert(FIPos < MI.getNumOperands() &&
    201            "Instr doesn't have FrameIndex operand!");
    202   }
    203   int FrameIndex = MI.getOperand(FIPos).getIndex();
    204   assert(FIPos+1 < MI.getNumOperands() && MI.getOperand(FIPos+1).isImm());
    205   int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex)
    206     + MI.getOperand(FIPos+1).getImm();
    207   unsigned BaseReg = BF::FP;
    208   if (TFI->hasFP(MF)) {
    209     assert(SPAdj==0 && "Unexpected SP adjust in function with frame pointer");
    210   } else {
    211     BaseReg = BF::SP;
    212     Offset += MF.getFrameInfo()->getStackSize() + SPAdj;
    213   }
    214 
    215   bool isStore = false;
    216 
    217   switch (MI.getOpcode()) {
    218   case BF::STORE32fi:
    219     isStore = true;
    220   case BF::LOAD32fi: {
    221     assert(Offset%4 == 0 && "Unaligned i32 stack access");
    222     assert(FIPos==1 && "Bad frame index operand");
    223     MI.getOperand(FIPos).ChangeToRegister(BaseReg, false);
    224     MI.getOperand(FIPos+1).setImm(Offset);
    225     if (isUInt<6>(Offset)) {
    226       MI.setDesc(TII.get(isStore
    227                          ? BF::STORE32p_uimm6m4
    228                          : BF::LOAD32p_uimm6m4));
    229       return;
    230     }
    231     if (BaseReg == BF::FP && isUInt<7>(-Offset)) {
    232       MI.setDesc(TII.get(isStore
    233                          ? BF::STORE32fp_nimm7m4
    234                          : BF::LOAD32fp_nimm7m4));
    235       MI.getOperand(FIPos+1).setImm(-Offset);
    236       return;
    237     }
    238     if (isInt<18>(Offset)) {
    239       MI.setDesc(TII.get(isStore
    240                          ? BF::STORE32p_imm18m4
    241                          : BF::LOAD32p_imm18m4));
    242       return;
    243     }
    244     // Use RegScavenger to calculate proper offset...
    245     MI.dump();
    246     llvm_unreachable("Stack frame offset too big");
    247     break;
    248   }
    249   case BF::ADDpp: {
    250     assert(MI.getOperand(0).isReg() && "ADD instruction needs a register");
    251     unsigned DestReg = MI.getOperand(0).getReg();
    252     // We need to produce a stack offset in a P register. We emit:
    253     // P0 = offset;
    254     // P0 = BR + P0;
    255     assert(FIPos==1 && "Bad frame index operand");
    256     loadConstant(MBB, II, DL, DestReg, Offset);
    257     MI.getOperand(1).ChangeToRegister(DestReg, false, false, true);
    258     MI.getOperand(2).ChangeToRegister(BaseReg, false);
    259     break;
    260   }
    261   case BF::STORE16fi:
    262     isStore = true;
    263   case BF::LOAD16fi: {
    264     assert(Offset%2 == 0 && "Unaligned i16 stack access");
    265     assert(FIPos==1 && "Bad frame index operand");
    266     // We need a P register to use as an address
    267     unsigned ScratchReg = findScratchRegister(II, RS, &BF::PRegClass, SPAdj);
    268     assert(ScratchReg && "Could not scavenge register");
    269     loadConstant(MBB, II, DL, ScratchReg, Offset);
    270     BuildMI(MBB, II, DL, TII.get(BF::ADDpp), ScratchReg)
    271       .addReg(ScratchReg, RegState::Kill)
    272       .addReg(BaseReg);
    273     MI.setDesc(TII.get(isStore ? BF::STORE16pi : BF::LOAD16pi));
    274     MI.getOperand(1).ChangeToRegister(ScratchReg, false, false, true);
    275     MI.RemoveOperand(2);
    276     break;
    277   }
    278   case BF::STORE8fi: {
    279     // This is an AnyCC spill, we need a scratch register.
    280     assert(FIPos==1 && "Bad frame index operand");
    281     MachineOperand SpillReg = MI.getOperand(0);
    282     unsigned ScratchReg = findScratchRegister(II, RS, &BF::DRegClass, SPAdj);
    283     assert(ScratchReg && "Could not scavenge register");
    284     if (SpillReg.getReg()==BF::NCC) {
    285       BuildMI(MBB, II, DL, TII.get(BF::MOVENCC_z), ScratchReg)
    286         .addOperand(SpillReg);
    287       BuildMI(MBB, II, DL, TII.get(BF::BITTGL), ScratchReg)
    288         .addReg(ScratchReg).addImm(0);
    289     } else {
    290       BuildMI(MBB, II, DL, TII.get(BF::MOVECC_zext), ScratchReg)
    291         .addOperand(SpillReg);
    292     }
    293     // STORE D
    294     MI.setDesc(TII.get(BF::STORE8p_imm16));
    295     MI.getOperand(0).ChangeToRegister(ScratchReg, false, false, true);
    296     MI.getOperand(FIPos).ChangeToRegister(BaseReg, false);
    297     MI.getOperand(FIPos+1).setImm(Offset);
    298     break;
    299   }
    300   case BF::LOAD8fi: {
    301     // This is an restore, we need a scratch register.
    302     assert(FIPos==1 && "Bad frame index operand");
    303     MachineOperand SpillReg = MI.getOperand(0);
    304     unsigned ScratchReg = findScratchRegister(II, RS, &BF::DRegClass, SPAdj);
    305     assert(ScratchReg && "Could not scavenge register");
    306     MI.setDesc(TII.get(BF::LOAD32p_imm16_8z));
    307     MI.getOperand(0).ChangeToRegister(ScratchReg, true);
    308     MI.getOperand(FIPos).ChangeToRegister(BaseReg, false);
    309     MI.getOperand(FIPos+1).setImm(Offset);
    310     ++II;
    311     if (SpillReg.getReg()==BF::CC) {
    312       // CC = D
    313       BuildMI(MBB, II, DL, TII.get(BF::MOVECC_nz), BF::CC)
    314         .addReg(ScratchReg, RegState::Kill);
    315     } else {
    316       // Restore NCC (CC = D==0)
    317       BuildMI(MBB, II, DL, TII.get(BF::SETEQri_not), BF::NCC)
    318         .addReg(ScratchReg, RegState::Kill)
    319         .addImm(0);
    320     }
    321     break;
    322   }
    323   default:
    324     llvm_unreachable("Cannot eliminate frame index");
    325     break;
    326   }
    327 }
    328 
    329 unsigned
    330 BlackfinRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
    331   const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
    332 
    333   return TFI->hasFP(MF) ? BF::FP : BF::SP;
    334 }
    335 
    336 unsigned BlackfinRegisterInfo::getEHExceptionRegister() const {
    337   llvm_unreachable("What is the exception register");
    338   return 0;
    339 }
    340 
    341 unsigned BlackfinRegisterInfo::getEHHandlerRegister() const {
    342   llvm_unreachable("What is the exception handler register");
    343   return 0;
    344 }
    345