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 // TODO: this implementation is a temporary placeholder which does just 114 // enough to allow other aspects of code generation to be tested. 115 116 assert(SPAdj == 0 && "Unexpected non-zero SPAdj value"); 117 118 MachineInstr &MI = *II; 119 MachineFunction &MF = *MI.getParent()->getParent(); 120 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); 121 DebugLoc DL = MI.getDebugLoc(); 122 123 int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 124 Register FrameReg; 125 StackOffset Offset = 126 TFI->getFrameIndexReference(MF, FrameIndex, FrameReg) + 127 StackOffset::getFixed(MI.getOperand(FIOperandNum + 1).getImm()); 128 129 // Offsets must be encodable with a 12-bit immediate field. 130 if (!isInt<12>(Offset.getFixed())) { 131 report_fatal_error("Frame offsets outside of the signed 12-bit range is " 132 "not supported currently"); 133 } 134 135 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false); 136 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset.getFixed()); 137 } 138