LCOV - code coverage report
Current view: top level - lib/Target/AVR - AVRRegisterInfo.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 77 81 95.1 %
Date: 2018-10-20 13:21:21 Functions: 9 10 90.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- AVRRegisterInfo.cpp - AVR Register 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 AVR implementation of the TargetRegisterInfo class.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #include "AVRRegisterInfo.h"
      15             : 
      16             : #include "llvm/ADT/BitVector.h"
      17             : #include "llvm/CodeGen/MachineFrameInfo.h"
      18             : #include "llvm/CodeGen/MachineFunction.h"
      19             : #include "llvm/CodeGen/MachineInstrBuilder.h"
      20             : #include "llvm/IR/Function.h"
      21             : #include "llvm/CodeGen/TargetFrameLowering.h"
      22             : 
      23             : #include "AVR.h"
      24             : #include "AVRInstrInfo.h"
      25             : #include "AVRTargetMachine.h"
      26             : #include "MCTargetDesc/AVRMCTargetDesc.h"
      27             : 
      28             : #define GET_REGINFO_TARGET_DESC
      29             : #include "AVRGenRegisterInfo.inc"
      30             : 
      31             : namespace llvm {
      32             : 
      33         119 : AVRRegisterInfo::AVRRegisterInfo() : AVRGenRegisterInfo(0) {}
      34             : 
      35             : const uint16_t *
      36        1819 : AVRRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
      37        1819 :   CallingConv::ID CC = MF->getFunction().getCallingConv();
      38             : 
      39        1819 :   return ((CC == CallingConv::AVR_INTR || CC == CallingConv::AVR_SIGNAL)
      40        1819 :               ? CSR_Interrupts_SaveList
      41        1819 :               : CSR_Normal_SaveList);
      42             : }
      43             : 
      44             : const uint32_t *
      45         137 : AVRRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
      46             :                                       CallingConv::ID CC) const {
      47         137 :   return ((CC == CallingConv::AVR_INTR || CC == CallingConv::AVR_SIGNAL)
      48             :               ? CSR_Interrupts_RegMask
      49         137 :               : CSR_Normal_RegMask);
      50             : }
      51             : 
      52         649 : BitVector AVRRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
      53         649 :   BitVector Reserved(getNumRegs());
      54             : 
      55             :   // Reserve the intermediate result registers r1 and r2
      56             :   // The result of instructions like 'mul' is always stored here.
      57             :   Reserved.set(AVR::R0);
      58             :   Reserved.set(AVR::R1);
      59             :   Reserved.set(AVR::R1R0);
      60             : 
      61             :   //  Reserve the stack pointer.
      62             :   Reserved.set(AVR::SPL);
      63             :   Reserved.set(AVR::SPH);
      64             :   Reserved.set(AVR::SP);
      65             : 
      66             :   // We tenatively reserve the frame pointer register r29:r28 because the
      67             :   // function may require one, but we cannot tell until register allocation
      68             :   // is complete, which can be too late.
      69             :   //
      70             :   // Instead we just unconditionally reserve the Y register.
      71             :   //
      72             :   // TODO: Write a pass to enumerate functions which reserved the Y register
      73             :   //       but didn't end up needing a frame pointer. In these, we can
      74             :   //       convert one or two of the spills inside to use the Y register.
      75             :   Reserved.set(AVR::R28);
      76             :   Reserved.set(AVR::R29);
      77             :   Reserved.set(AVR::R29R28);
      78             : 
      79         649 :   return Reserved;
      80             : }
      81             : 
      82             : const TargetRegisterClass *
      83         804 : AVRRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
      84             :                                            const MachineFunction &MF) const {
      85         804 :   const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
      86         804 :   if (TRI->isTypeLegalForClass(*RC, MVT::i16)) {
      87             :     return &AVR::DREGSRegClass;
      88             :   }
      89             : 
      90         201 :   if (TRI->isTypeLegalForClass(*RC, MVT::i8)) {
      91             :     return &AVR::GPR8RegClass;
      92             :   }
      93             : 
      94           0 :   llvm_unreachable("Invalid register size");
      95             : }
      96             : 
      97             : /// Fold a frame offset shared between two add instructions into a single one.
      98          26 : static void foldFrameOffset(MachineBasicBlock::iterator &II, int &Offset, unsigned DstReg) {
      99             :   MachineInstr &MI = *II;
     100          26 :   int Opcode = MI.getOpcode();
     101             : 
     102             :   // Don't bother trying if the next instruction is not an add or a sub.
     103          26 :   if ((Opcode != AVR::SUBIWRdK) && (Opcode != AVR::ADIWRdK)) {
     104             :     return;
     105             :   }
     106             : 
     107             :   // Check that DstReg matches with next instruction, otherwise the instruction
     108             :   // is not related to stack address manipulation.
     109           5 :   if (DstReg != MI.getOperand(0).getReg()) {
     110             :     return;
     111             :   }
     112             : 
     113             :   // Add the offset in the next instruction to our offset.
     114           5 :   switch (Opcode) {
     115           1 :   case AVR::SUBIWRdK:
     116           1 :     Offset += -MI.getOperand(2).getImm();
     117           1 :     break;
     118           4 :   case AVR::ADIWRdK:
     119           4 :     Offset += MI.getOperand(2).getImm();
     120           4 :     break;
     121             :   }
     122             : 
     123             :   // Finally remove the instruction.
     124             :   II++;
     125           5 :   MI.eraseFromParent();
     126             : }
     127             : 
     128         169 : void AVRRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
     129             :                                           int SPAdj, unsigned FIOperandNum,
     130             :                                           RegScavenger *RS) const {
     131             :   assert(SPAdj == 0 && "Unexpected SPAdj value");
     132             : 
     133             :   MachineInstr &MI = *II;
     134             :   DebugLoc dl = MI.getDebugLoc();
     135         169 :   MachineBasicBlock &MBB = *MI.getParent();
     136         169 :   const MachineFunction &MF = *MBB.getParent();
     137         169 :   const AVRTargetMachine &TM = (const AVRTargetMachine &)MF.getTarget();
     138         169 :   const TargetInstrInfo &TII = *TM.getSubtargetImpl()->getInstrInfo();
     139         169 :   const MachineFrameInfo &MFI = MF.getFrameInfo();
     140         169 :   const TargetFrameLowering *TFI = TM.getSubtargetImpl()->getFrameLowering();
     141         338 :   int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
     142         169 :   int Offset = MFI.getObjectOffset(FrameIndex);
     143             : 
     144             :   // Add one to the offset because SP points to an empty slot.
     145         169 :   Offset += MFI.getStackSize() - TFI->getOffsetOfLocalArea() + 1;
     146             :   // Fold incoming offset.
     147         169 :   Offset += MI.getOperand(FIOperandNum + 1).getImm();
     148             : 
     149             :   // This is actually "load effective address" of the stack slot
     150             :   // instruction. We have only two-address instructions, thus we need to
     151             :   // expand it into move + add.
     152         338 :   if (MI.getOpcode() == AVR::FRMIDX) {
     153          27 :     MI.setDesc(TII.get(AVR::MOVWRdRr));
     154          27 :     MI.getOperand(FIOperandNum).ChangeToRegister(AVR::R29R28, false);
     155             : 
     156             :     assert(Offset > 0 && "Invalid offset");
     157             : 
     158             :     // We need to materialize the offset via an add instruction.
     159             :     unsigned Opcode;
     160          27 :     unsigned DstReg = MI.getOperand(0).getReg();
     161             :     assert(DstReg != AVR::R29R28 && "Dest reg cannot be the frame pointer");
     162             : 
     163             :     II++; // Skip over the FRMIDX (and now MOVW) instruction.
     164             : 
     165             :     // Generally, to load a frame address two add instructions are emitted that
     166             :     // could get folded into a single one:
     167             :     //  movw    r31:r30, r29:r28
     168             :     //  adiw    r31:r30, 29
     169             :     //  adiw    r31:r30, 16
     170             :     // to:
     171             :     //  movw    r31:r30, r29:r28
     172             :     //  adiw    r31:r30, 45
     173          27 :     if (II != MBB.end())
     174          26 :       foldFrameOffset(II, Offset, DstReg);
     175             : 
     176             :     // Select the best opcode based on DstReg and the offset size.
     177             :     switch (DstReg) {
     178          22 :     case AVR::R25R24:
     179             :     case AVR::R27R26:
     180             :     case AVR::R31R30: {
     181          22 :       if (isUInt<6>(Offset)) {
     182             :         Opcode = AVR::ADIWRdK;
     183             :         break;
     184             :       }
     185             :       LLVM_FALLTHROUGH;
     186             :     }
     187             :     default: {
     188             :       // This opcode will get expanded into a pair of subi/sbci.
     189             :       Opcode = AVR::SUBIWRdK;
     190           7 :       Offset = -Offset;
     191           7 :       break;
     192             :     }
     193             :     }
     194             : 
     195          54 :     MachineInstr *New = BuildMI(MBB, II, dl, TII.get(Opcode), DstReg)
     196          27 :                             .addReg(DstReg, RegState::Kill)
     197          27 :                             .addImm(Offset);
     198          27 :     New->getOperand(3).setIsDead();
     199             : 
     200             :     return;
     201             :   }
     202             : 
     203             :   // If the offset is too big we have to adjust and restore the frame pointer
     204             :   // to materialize a valid load/store with displacement.
     205             :   //:TODO: consider using only one adiw/sbiw chain for more than one frame index
     206         142 :   if (Offset > 62) {
     207             :     unsigned AddOpc = AVR::ADIWRdK, SubOpc = AVR::SBIWRdK;
     208          16 :     int AddOffset = Offset - 63 + 1;
     209             : 
     210             :     // For huge offsets where adiw/sbiw cannot be used use a pair of subi/sbci.
     211          16 :     if ((Offset - 63 + 1) > 63) {
     212             :       AddOpc = AVR::SUBIWRdK;
     213             :       SubOpc = AVR::SUBIWRdK;
     214           1 :       AddOffset = -AddOffset;
     215             :     }
     216             : 
     217             :     // It is possible that the spiller places this frame instruction in between
     218             :     // a compare and branch, invalidating the contents of SREG set by the
     219             :     // compare instruction because of the add/sub pairs. Conservatively save and
     220             :     // restore SREG before and after each add/sub pair.
     221          32 :     BuildMI(MBB, II, dl, TII.get(AVR::INRdA), AVR::R0).addImm(0x3f);
     222             : 
     223          32 :     MachineInstr *New = BuildMI(MBB, II, dl, TII.get(AddOpc), AVR::R29R28)
     224          16 :                             .addReg(AVR::R29R28, RegState::Kill)
     225          16 :                             .addImm(AddOffset);
     226          16 :     New->getOperand(3).setIsDead();
     227             : 
     228             :     // Restore SREG.
     229          16 :     BuildMI(MBB, std::next(II), dl, TII.get(AVR::OUTARr))
     230             :         .addImm(0x3f)
     231          16 :         .addReg(AVR::R0, RegState::Kill);
     232             : 
     233             :     // No need to set SREG as dead here otherwise if the next instruction is a
     234             :     // cond branch it will be using a dead register.
     235          16 :     New = BuildMI(MBB, std::next(II), dl, TII.get(SubOpc), AVR::R29R28)
     236          16 :               .addReg(AVR::R29R28, RegState::Kill)
     237          16 :               .addImm(Offset - 63 + 1);
     238             : 
     239          16 :     Offset = 62;
     240             :   }
     241             : 
     242         284 :   MI.getOperand(FIOperandNum).ChangeToRegister(AVR::R29R28, false);
     243             :   assert(isUInt<6>(Offset) && "Offset is out of range");
     244         284 :   MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
     245             : }
     246             : 
     247        4161 : unsigned AVRRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
     248        4161 :   const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
     249        4161 :   if (TFI->hasFP(MF)) {
     250             :     // The Y pointer register
     251           0 :     return AVR::R28;
     252             :   }
     253             : 
     254             :   return AVR::SP;
     255             : }
     256             : 
     257             : const TargetRegisterClass *
     258           0 : AVRRegisterInfo::getPointerRegClass(const MachineFunction &MF,
     259             :                                     unsigned Kind) const {
     260             :   // FIXME: Currently we're using avr-gcc as reference, so we restrict
     261             :   // ptrs to Y and Z regs. Though avr-gcc has buggy implementation
     262             :   // of memory constraint, so we can fix it and bit avr-gcc here ;-)
     263           0 :   return &AVR::PTRDISPREGSRegClass;
     264             : }
     265             : 
     266        1928 : void AVRRegisterInfo::splitReg(unsigned Reg,
     267             :                                unsigned &LoReg,
     268             :                                unsigned &HiReg) const {
     269             :     assert(AVR::DREGSRegClass.contains(Reg) && "can only split 16-bit registers");
     270             : 
     271        1928 :     LoReg = getSubReg(Reg, AVR::sub_lo);
     272        1928 :     HiReg = getSubReg(Reg, AVR::sub_hi);
     273        1928 : }
     274             : 
     275             : } // end of namespace llvm

Generated by: LCOV version 1.13