xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchRegisterInfo.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
1*81ad6265SDimitry Andric //===- LoongArchRegisterInfo.cpp - LoongArch Register Information -*- C++ -*-=//
2*81ad6265SDimitry Andric //
3*81ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*81ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*81ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*81ad6265SDimitry Andric //
7*81ad6265SDimitry Andric //===----------------------------------------------------------------------===//
8*81ad6265SDimitry Andric //
9*81ad6265SDimitry Andric // This file contains the LoongArch implementation of the TargetRegisterInfo
10*81ad6265SDimitry Andric // class.
11*81ad6265SDimitry Andric //
12*81ad6265SDimitry Andric //===----------------------------------------------------------------------===//
13*81ad6265SDimitry Andric 
14*81ad6265SDimitry Andric #include "LoongArchRegisterInfo.h"
15*81ad6265SDimitry Andric #include "LoongArch.h"
16*81ad6265SDimitry Andric #include "LoongArchSubtarget.h"
17*81ad6265SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
18*81ad6265SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
19*81ad6265SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
20*81ad6265SDimitry Andric #include "llvm/CodeGen/RegisterScavenging.h"
21*81ad6265SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
22*81ad6265SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
23*81ad6265SDimitry Andric #include "llvm/Support/ErrorHandling.h"
24*81ad6265SDimitry Andric 
25*81ad6265SDimitry Andric using namespace llvm;
26*81ad6265SDimitry Andric 
27*81ad6265SDimitry Andric #define GET_REGINFO_TARGET_DESC
28*81ad6265SDimitry Andric #include "LoongArchGenRegisterInfo.inc"
29*81ad6265SDimitry Andric 
30*81ad6265SDimitry Andric LoongArchRegisterInfo::LoongArchRegisterInfo(unsigned HwMode)
31*81ad6265SDimitry Andric     : LoongArchGenRegisterInfo(LoongArch::R1, /*DwarfFlavour*/ 0,
32*81ad6265SDimitry Andric                                /*EHFlavor*/ 0,
33*81ad6265SDimitry Andric                                /*PC*/ 0, HwMode) {}
34*81ad6265SDimitry Andric 
35*81ad6265SDimitry Andric const MCPhysReg *
36*81ad6265SDimitry Andric LoongArchRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
37*81ad6265SDimitry Andric   auto &Subtarget = MF->getSubtarget<LoongArchSubtarget>();
38*81ad6265SDimitry Andric 
39*81ad6265SDimitry Andric   switch (Subtarget.getTargetABI()) {
40*81ad6265SDimitry Andric   default:
41*81ad6265SDimitry Andric     llvm_unreachable("Unrecognized ABI");
42*81ad6265SDimitry Andric   case LoongArchABI::ABI_ILP32S:
43*81ad6265SDimitry Andric   case LoongArchABI::ABI_LP64S:
44*81ad6265SDimitry Andric     return CSR_ILP32S_LP64S_SaveList;
45*81ad6265SDimitry Andric   case LoongArchABI::ABI_ILP32F:
46*81ad6265SDimitry Andric   case LoongArchABI::ABI_LP64F:
47*81ad6265SDimitry Andric     return CSR_ILP32F_LP64F_SaveList;
48*81ad6265SDimitry Andric   case LoongArchABI::ABI_ILP32D:
49*81ad6265SDimitry Andric   case LoongArchABI::ABI_LP64D:
50*81ad6265SDimitry Andric     return CSR_ILP32D_LP64D_SaveList;
51*81ad6265SDimitry Andric   }
52*81ad6265SDimitry Andric }
53*81ad6265SDimitry Andric 
54*81ad6265SDimitry Andric const uint32_t *
55*81ad6265SDimitry Andric LoongArchRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
56*81ad6265SDimitry Andric                                             CallingConv::ID CC) const {
57*81ad6265SDimitry Andric   auto &Subtarget = MF.getSubtarget<LoongArchSubtarget>();
58*81ad6265SDimitry Andric 
59*81ad6265SDimitry Andric   switch (Subtarget.getTargetABI()) {
60*81ad6265SDimitry Andric   default:
61*81ad6265SDimitry Andric     llvm_unreachable("Unrecognized ABI");
62*81ad6265SDimitry Andric   case LoongArchABI::ABI_ILP32S:
63*81ad6265SDimitry Andric   case LoongArchABI::ABI_LP64S:
64*81ad6265SDimitry Andric     return CSR_ILP32S_LP64S_RegMask;
65*81ad6265SDimitry Andric   case LoongArchABI::ABI_ILP32F:
66*81ad6265SDimitry Andric   case LoongArchABI::ABI_LP64F:
67*81ad6265SDimitry Andric     return CSR_ILP32F_LP64F_RegMask;
68*81ad6265SDimitry Andric   case LoongArchABI::ABI_ILP32D:
69*81ad6265SDimitry Andric   case LoongArchABI::ABI_LP64D:
70*81ad6265SDimitry Andric     return CSR_ILP32D_LP64D_RegMask;
71*81ad6265SDimitry Andric   }
72*81ad6265SDimitry Andric }
73*81ad6265SDimitry Andric 
74*81ad6265SDimitry Andric const uint32_t *LoongArchRegisterInfo::getNoPreservedMask() const {
75*81ad6265SDimitry Andric   return CSR_NoRegs_RegMask;
76*81ad6265SDimitry Andric }
77*81ad6265SDimitry Andric 
78*81ad6265SDimitry Andric BitVector
79*81ad6265SDimitry Andric LoongArchRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
80*81ad6265SDimitry Andric   const LoongArchFrameLowering *TFI = getFrameLowering(MF);
81*81ad6265SDimitry Andric   BitVector Reserved(getNumRegs());
82*81ad6265SDimitry Andric 
83*81ad6265SDimitry Andric   // Use markSuperRegs to ensure any register aliases are also reserved
84*81ad6265SDimitry Andric   markSuperRegs(Reserved, LoongArch::R0);  // zero
85*81ad6265SDimitry Andric   markSuperRegs(Reserved, LoongArch::R2);  // tp
86*81ad6265SDimitry Andric   markSuperRegs(Reserved, LoongArch::R3);  // sp
87*81ad6265SDimitry Andric   markSuperRegs(Reserved, LoongArch::R21); // non-allocatable
88*81ad6265SDimitry Andric   if (TFI->hasFP(MF))
89*81ad6265SDimitry Andric     markSuperRegs(Reserved, LoongArch::R22); // fp
90*81ad6265SDimitry Andric   // Reserve the base register if we need to realign the stack and allocate
91*81ad6265SDimitry Andric   // variable-sized objects at runtime.
92*81ad6265SDimitry Andric   if (TFI->hasBP(MF))
93*81ad6265SDimitry Andric     markSuperRegs(Reserved, LoongArchABI::getBPReg()); // bp
94*81ad6265SDimitry Andric 
95*81ad6265SDimitry Andric   assert(checkAllSuperRegsMarked(Reserved));
96*81ad6265SDimitry Andric   return Reserved;
97*81ad6265SDimitry Andric }
98*81ad6265SDimitry Andric 
99*81ad6265SDimitry Andric bool LoongArchRegisterInfo::isConstantPhysReg(MCRegister PhysReg) const {
100*81ad6265SDimitry Andric   return PhysReg == LoongArch::R0;
101*81ad6265SDimitry Andric }
102*81ad6265SDimitry Andric 
103*81ad6265SDimitry Andric Register
104*81ad6265SDimitry Andric LoongArchRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
105*81ad6265SDimitry Andric   const TargetFrameLowering *TFI = getFrameLowering(MF);
106*81ad6265SDimitry Andric   return TFI->hasFP(MF) ? LoongArch::R22 : LoongArch::R3;
107*81ad6265SDimitry Andric }
108*81ad6265SDimitry Andric 
109*81ad6265SDimitry Andric void LoongArchRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
110*81ad6265SDimitry Andric                                                 int SPAdj,
111*81ad6265SDimitry Andric                                                 unsigned FIOperandNum,
112*81ad6265SDimitry Andric                                                 RegScavenger *RS) const {
113*81ad6265SDimitry Andric   assert(SPAdj == 0 && "Unexpected non-zero SPAdj value");
114*81ad6265SDimitry Andric   // TODO: Implement this when we have function calls
115*81ad6265SDimitry Andric }
116