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