brintos

brintos / llvm-project-archived public Read only

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