xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Mips/Mips16RegisterInfo.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
10b57cec5SDimitry Andric //===-- Mips16RegisterInfo.cpp - MIPS16 Register Information --------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file contains the MIPS16 implementation of the TargetRegisterInfo class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "Mips16RegisterInfo.h"
140b57cec5SDimitry Andric #include "Mips.h"
150b57cec5SDimitry Andric #include "Mips16InstrInfo.h"
160b57cec5SDimitry Andric #include "MipsInstrInfo.h"
170b57cec5SDimitry Andric #include "MipsMachineFunction.h"
180b57cec5SDimitry Andric #include "MipsSubtarget.h"
190b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
210b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
220b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
230b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
240b57cec5SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
250b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
260b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
270b57cec5SDimitry Andric #include "llvm/IR/DebugInfo.h"
280b57cec5SDimitry Andric #include "llvm/IR/Function.h"
290b57cec5SDimitry Andric #include "llvm/IR/Type.h"
300b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
310b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
320b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
330b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
340b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h"
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric using namespace llvm;
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric #define DEBUG_TYPE "mips16-registerinfo"
390b57cec5SDimitry Andric 
40*81ad6265SDimitry Andric Mips16RegisterInfo::Mips16RegisterInfo() = default;
410b57cec5SDimitry Andric 
requiresRegisterScavenging(const MachineFunction & MF) const420b57cec5SDimitry Andric bool Mips16RegisterInfo::requiresRegisterScavenging
430b57cec5SDimitry Andric   (const MachineFunction &MF) const {
440b57cec5SDimitry Andric   return false;
450b57cec5SDimitry Andric }
requiresFrameIndexScavenging(const MachineFunction & MF) const460b57cec5SDimitry Andric bool Mips16RegisterInfo::requiresFrameIndexScavenging
470b57cec5SDimitry Andric   (const MachineFunction &MF) const {
480b57cec5SDimitry Andric   return false;
490b57cec5SDimitry Andric }
500b57cec5SDimitry Andric 
useFPForScavengingIndex(const MachineFunction & MF) const510b57cec5SDimitry Andric bool Mips16RegisterInfo::useFPForScavengingIndex
520b57cec5SDimitry Andric   (const MachineFunction &MF) const {
530b57cec5SDimitry Andric   return false;
540b57cec5SDimitry Andric }
550b57cec5SDimitry Andric 
saveScavengerRegister(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,MachineBasicBlock::iterator & UseMI,const TargetRegisterClass * RC,Register Reg) const565ffd83dbSDimitry Andric bool Mips16RegisterInfo::saveScavengerRegister(
575ffd83dbSDimitry Andric     MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
585ffd83dbSDimitry Andric     MachineBasicBlock::iterator &UseMI, const TargetRegisterClass *RC,
595ffd83dbSDimitry Andric     Register Reg) const {
600b57cec5SDimitry Andric   DebugLoc DL;
610b57cec5SDimitry Andric   const TargetInstrInfo &TII = *MBB.getParent()->getSubtarget().getInstrInfo();
620b57cec5SDimitry Andric   TII.copyPhysReg(MBB, I, DL, Mips::T0, Reg, true);
630b57cec5SDimitry Andric   TII.copyPhysReg(MBB, UseMI, DL, Reg, Mips::T0, true);
640b57cec5SDimitry Andric   return true;
650b57cec5SDimitry Andric }
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric const TargetRegisterClass *
intRegClass(unsigned Size) const680b57cec5SDimitry Andric Mips16RegisterInfo::intRegClass(unsigned Size) const {
690b57cec5SDimitry Andric   assert(Size == 4);
700b57cec5SDimitry Andric   return &Mips::CPU16RegsRegClass;
710b57cec5SDimitry Andric }
720b57cec5SDimitry Andric 
eliminateFI(MachineBasicBlock::iterator II,unsigned OpNo,int FrameIndex,uint64_t StackSize,int64_t SPOffset) const730b57cec5SDimitry Andric void Mips16RegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
740b57cec5SDimitry Andric                                      unsigned OpNo, int FrameIndex,
750b57cec5SDimitry Andric                                      uint64_t StackSize,
760b57cec5SDimitry Andric                                      int64_t SPOffset) const {
770b57cec5SDimitry Andric   MachineInstr &MI = *II;
780b57cec5SDimitry Andric   MachineFunction &MF = *MI.getParent()->getParent();
790b57cec5SDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric   const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
820b57cec5SDimitry Andric   int MinCSFI = 0;
830b57cec5SDimitry Andric   int MaxCSFI = -1;
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   if (CSI.size()) {
860b57cec5SDimitry Andric     MinCSFI = CSI[0].getFrameIdx();
870b57cec5SDimitry Andric     MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
880b57cec5SDimitry Andric   }
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric   // The following stack frame objects are always
910b57cec5SDimitry Andric   // referenced relative to $sp:
920b57cec5SDimitry Andric   //  1. Outgoing arguments.
930b57cec5SDimitry Andric   //  2. Pointer to dynamically allocated stack space.
940b57cec5SDimitry Andric   //  3. Locations for callee-saved registers.
950b57cec5SDimitry Andric   // Everything else is referenced relative to whatever register
960b57cec5SDimitry Andric   // getFrameRegister() returns.
975ffd83dbSDimitry Andric   Register FrameReg;
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   if (FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI)
1000b57cec5SDimitry Andric     FrameReg = Mips::SP;
1010b57cec5SDimitry Andric   else {
1020b57cec5SDimitry Andric     const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
1030b57cec5SDimitry Andric     if (TFI->hasFP(MF)) {
1040b57cec5SDimitry Andric       FrameReg = Mips::S0;
1050b57cec5SDimitry Andric     }
1060b57cec5SDimitry Andric     else {
1070b57cec5SDimitry Andric       if ((MI.getNumOperands()> OpNo+2) && MI.getOperand(OpNo+2).isReg())
1080b57cec5SDimitry Andric         FrameReg = MI.getOperand(OpNo+2).getReg();
1090b57cec5SDimitry Andric       else
1100b57cec5SDimitry Andric         FrameReg = Mips::SP;
1110b57cec5SDimitry Andric     }
1120b57cec5SDimitry Andric   }
1130b57cec5SDimitry Andric   // Calculate final offset.
1140b57cec5SDimitry Andric   // - There is no need to change the offset if the frame object
1150b57cec5SDimitry Andric   //   is one of the
1160b57cec5SDimitry Andric   //   following: an outgoing argument, pointer to a dynamically allocated
1170b57cec5SDimitry Andric   //   stack space or a $gp restore location,
1180b57cec5SDimitry Andric   // - If the frame object is any of the following,
1190b57cec5SDimitry Andric   //   its offset must be adjusted
1200b57cec5SDimitry Andric   //   by adding the size of the stack:
1210b57cec5SDimitry Andric   //   incoming argument, callee-saved register location or local variable.
1220b57cec5SDimitry Andric   int64_t Offset;
1230b57cec5SDimitry Andric   bool IsKill = false;
1240b57cec5SDimitry Andric   Offset = SPOffset + (int64_t)StackSize;
1250b57cec5SDimitry Andric   Offset += MI.getOperand(OpNo + 1).getImm();
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric   LLVM_DEBUG(errs() << "Offset     : " << Offset << "\n"
1280b57cec5SDimitry Andric                     << "<--------->\n");
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric   if (!MI.isDebugValue() &&
1310b57cec5SDimitry Andric       !Mips16InstrInfo::validImmediate(MI.getOpcode(), FrameReg, Offset)) {
1320b57cec5SDimitry Andric     MachineBasicBlock &MBB = *MI.getParent();
1330b57cec5SDimitry Andric     DebugLoc DL = II->getDebugLoc();
1340b57cec5SDimitry Andric     unsigned NewImm;
1350b57cec5SDimitry Andric     const Mips16InstrInfo &TII =
1360b57cec5SDimitry Andric         *static_cast<const Mips16InstrInfo *>(MF.getSubtarget().getInstrInfo());
1370b57cec5SDimitry Andric     FrameReg = TII.loadImmediate(FrameReg, Offset, MBB, II, DL, NewImm);
1380b57cec5SDimitry Andric     Offset = SignExtend64<16>(NewImm);
1390b57cec5SDimitry Andric     IsKill = true;
1400b57cec5SDimitry Andric   }
1410b57cec5SDimitry Andric   MI.getOperand(OpNo).ChangeToRegister(FrameReg, false, false, IsKill);
1420b57cec5SDimitry Andric   MI.getOperand(OpNo + 1).ChangeToImmediate(Offset);
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric }
146