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