1 //===- XtensaRegisterInfo.cpp - Xtensa Register Information ---------------===// 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 Xtensa implementation of the TargetRegisterInfo class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "XtensaRegisterInfo.h" 14 #include "MCTargetDesc/XtensaMCTargetDesc.h" 15 #include "XtensaInstrInfo.h" 16 #include "XtensaSubtarget.h" 17 #include "llvm/CodeGen/MachineFrameInfo.h" 18 #include "llvm/CodeGen/MachineFunction.h" 19 #include "llvm/CodeGen/MachineInstrBuilder.h" 20 #include "llvm/CodeGen/MachineRegisterInfo.h" 21 #include "llvm/Support/Debug.h" 22 #include "llvm/Support/ErrorHandling.h" 23 #include "llvm/Support/raw_ostream.h" 24 25 #define DEBUG_TYPE "xtensa-reg-info" 26 27 #define GET_REGINFO_TARGET_DESC 28 #include "XtensaGenRegisterInfo.inc" 29 30 using namespace llvm; 31 32 XtensaRegisterInfo::XtensaRegisterInfo(const XtensaSubtarget &STI) 33 : XtensaGenRegisterInfo(Xtensa::A0), Subtarget(STI) {} 34 35 const uint16_t * 36 XtensaRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 37 return CSR_Xtensa_SaveList; 38 } 39 40 const uint32_t * 41 XtensaRegisterInfo::getCallPreservedMask(const MachineFunction &MF, 42 CallingConv::ID) const { 43 return CSR_Xtensa_RegMask; 44 } 45 46 BitVector XtensaRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 47 BitVector Reserved(getNumRegs()); 48 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); 49 50 Reserved.set(Xtensa::A0); 51 if (TFI->hasFP(MF)) { 52 // Reserve frame pointer. 53 Reserved.set(getFrameRegister(MF)); 54 } 55 56 // Reserve stack pointer. 57 Reserved.set(Xtensa::SP); 58 return Reserved; 59 } 60 61 bool XtensaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 62 int SPAdj, unsigned FIOperandNum, 63 RegScavenger *RS) const { 64 MachineInstr &MI = *II; 65 MachineFunction &MF = *MI.getParent()->getParent(); 66 int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 67 uint64_t StackSize = MF.getFrameInfo().getStackSize(); 68 int64_t SPOffset = MF.getFrameInfo().getObjectOffset(FrameIndex); 69 MachineFrameInfo &MFI = MF.getFrameInfo(); 70 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 71 int MinCSFI = 0; 72 int MaxCSFI = -1; 73 74 if (CSI.size()) { 75 MinCSFI = CSI[0].getFrameIdx(); 76 MaxCSFI = CSI[CSI.size() - 1].getFrameIdx(); 77 } 78 // The following stack frame objects are always referenced relative to $sp: 79 // 1. Outgoing arguments. 80 // 2. Pointer to dynamically allocated stack space. 81 // 3. Locations for callee-saved registers. 82 // 4. Locations for eh data registers. 83 // Everything else is referenced relative to whatever register 84 // getFrameRegister() returns. 85 unsigned FrameReg; 86 if ((FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI)) 87 FrameReg = Xtensa::SP; 88 else 89 FrameReg = getFrameRegister(MF); 90 91 // Calculate final offset. 92 // - There is no need to change the offset if the frame object is one of the 93 // following: an outgoing argument, pointer to a dynamically allocated 94 // stack space or a $gp restore location, 95 // - If the frame object is any of the following, its offset must be adjusted 96 // by adding the size of the stack: 97 // incoming argument, callee-saved register location or local variable. 98 bool IsKill = false; 99 int64_t Offset = 100 SPOffset + (int64_t)StackSize + MI.getOperand(FIOperandNum + 1).getImm(); 101 102 bool Valid = Xtensa::isValidAddrOffsetForOpcode(MI.getOpcode(), Offset); 103 104 // If MI is not a debug value, make sure Offset fits in the 16-bit immediate 105 // field. 106 if (!MI.isDebugValue() && !Valid) { 107 MachineBasicBlock &MBB = *MI.getParent(); 108 DebugLoc DL = II->getDebugLoc(); 109 unsigned ADD = Xtensa::ADD; 110 unsigned Reg; 111 const XtensaInstrInfo &TII = *static_cast<const XtensaInstrInfo *>( 112 MBB.getParent()->getSubtarget().getInstrInfo()); 113 114 TII.loadImmediate(MBB, II, &Reg, Offset); 115 BuildMI(MBB, II, DL, TII.get(ADD), Reg) 116 .addReg(FrameReg) 117 .addReg(Reg, RegState::Kill); 118 119 FrameReg = Reg; 120 Offset = 0; 121 IsKill = true; 122 } 123 124 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false, false, IsKill); 125 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 126 127 return false; 128 } 129 130 Register XtensaRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 131 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); 132 return TFI->hasFP(MF) ? Xtensa::A15 : Xtensa::SP; 133 } 134