Path: blob/main/contrib/llvm-project/llvm/lib/Target/Xtensa/XtensaRegisterInfo.cpp
96353 views
//===- XtensaRegisterInfo.cpp - Xtensa Register Information ---------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains the Xtensa implementation of the TargetRegisterInfo class.9//10//===----------------------------------------------------------------------===//1112#include "XtensaRegisterInfo.h"13#include "XtensaInstrInfo.h"14#include "XtensaSubtarget.h"15#include "XtensaUtils.h"16#include "llvm/CodeGen/MachineFrameInfo.h"17#include "llvm/CodeGen/MachineFunction.h"18#include "llvm/CodeGen/MachineInstrBuilder.h"19#include "llvm/CodeGen/MachineRegisterInfo.h"20#include "llvm/Support/Debug.h"21#include "llvm/Support/ErrorHandling.h"22#include "llvm/Support/raw_ostream.h"2324#define DEBUG_TYPE "xtensa-reg-info"2526#define GET_REGINFO_TARGET_DESC27#include "XtensaGenRegisterInfo.inc"2829using namespace llvm;3031XtensaRegisterInfo::XtensaRegisterInfo(const XtensaSubtarget &STI)32: XtensaGenRegisterInfo(Xtensa::A0), Subtarget(STI) {}3334const uint16_t *35XtensaRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {36return CSR_Xtensa_SaveList;37}3839const uint32_t *40XtensaRegisterInfo::getCallPreservedMask(const MachineFunction &MF,41CallingConv::ID) const {42return CSR_Xtensa_RegMask;43}4445BitVector XtensaRegisterInfo::getReservedRegs(const MachineFunction &MF) const {46BitVector Reserved(getNumRegs());47const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();4849Reserved.set(Xtensa::A0);50if (TFI->hasFP(MF)) {51// Reserve frame pointer.52Reserved.set(getFrameRegister(MF));53}5455// Reserve stack pointer.56Reserved.set(Xtensa::SP);57return Reserved;58}5960bool XtensaRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,61int SPAdj, unsigned FIOperandNum,62RegScavenger *RS) const {63MachineInstr &MI = *II;64MachineFunction &MF = *MI.getParent()->getParent();65int FrameIndex = MI.getOperand(FIOperandNum).getIndex();66uint64_t StackSize = MF.getFrameInfo().getStackSize();67int64_t SPOffset = MF.getFrameInfo().getObjectOffset(FrameIndex);68MachineFrameInfo &MFI = MF.getFrameInfo();69const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();70int MinCSFI = 0;71int MaxCSFI = -1;7273if (CSI.size()) {74MinCSFI = CSI[0].getFrameIdx();75MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();76}77// The following stack frame objects are always referenced relative to $sp:78// 1. Outgoing arguments.79// 2. Pointer to dynamically allocated stack space.80// 3. Locations for callee-saved registers.81// 4. Locations for eh data registers.82// Everything else is referenced relative to whatever register83// getFrameRegister() returns.84unsigned FrameReg;85if ((FrameIndex >= MinCSFI && FrameIndex <= MaxCSFI))86FrameReg = Xtensa::SP;87else88FrameReg = getFrameRegister(MF);8990// Calculate final offset.91// - There is no need to change the offset if the frame object is one of the92// following: an outgoing argument, pointer to a dynamically allocated93// stack space or a $gp restore location,94// - If the frame object is any of the following, its offset must be adjusted95// by adding the size of the stack:96// incoming argument, callee-saved register location or local variable.97bool IsKill = false;98int64_t Offset =99SPOffset + (int64_t)StackSize + MI.getOperand(FIOperandNum + 1).getImm();100101bool Valid = isValidAddrOffset(MI, Offset);102103// If MI is not a debug value, make sure Offset fits in the 16-bit immediate104// field.105if (!MI.isDebugValue() && !Valid) {106MachineBasicBlock &MBB = *MI.getParent();107DebugLoc DL = II->getDebugLoc();108unsigned ADD = Xtensa::ADD;109unsigned Reg;110const XtensaInstrInfo &TII = *static_cast<const XtensaInstrInfo *>(111MBB.getParent()->getSubtarget().getInstrInfo());112113TII.loadImmediate(MBB, II, &Reg, Offset);114BuildMI(MBB, II, DL, TII.get(ADD), Reg)115.addReg(FrameReg)116.addReg(Reg, RegState::Kill);117118FrameReg = Reg;119Offset = 0;120IsKill = true;121}122123MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false, false, IsKill);124MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);125126return false;127}128129Register XtensaRegisterInfo::getFrameRegister(const MachineFunction &MF) const {130const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();131return TFI->hasFP(MF) ? Xtensa::A15 : Xtensa::SP;132}133134135