brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.5 KiB · 77fb733 Raw
231 lines · cpp
1//===- MC/MCRegisterInfo.cpp - Target Register Description ----------------===//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 implements MCRegisterInfo functions.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/MC/MCRegisterInfo.h"14#include "llvm/ADT/DenseMap.h"15#include "llvm/ADT/Twine.h"16#include "llvm/Support/ErrorHandling.h"17#include <algorithm>18#include <cassert>19#include <cstdint>20 21using namespace llvm;22 23namespace {24/// MCRegAliasIterator enumerates all registers aliasing Reg.  This iterator25/// does not guarantee any ordering or that entries are unique.26class MCRegAliasIteratorImpl {27private:28  MCRegister Reg;29  const MCRegisterInfo *MCRI;30 31  MCRegUnitIterator RI;32  MCRegUnitRootIterator RRI;33  MCSuperRegIterator SI;34 35public:36  MCRegAliasIteratorImpl(MCRegister Reg, const MCRegisterInfo *MCRI)37      : Reg(Reg), MCRI(MCRI) {38 39    // Initialize the iterators.40    for (RI = MCRegUnitIterator(Reg, MCRI); RI.isValid(); ++RI) {41      for (RRI = MCRegUnitRootIterator(*RI, MCRI); RRI.isValid(); ++RRI) {42        for (SI = MCSuperRegIterator(*RRI, MCRI, true); SI.isValid(); ++SI) {43          if (Reg != *SI)44            return;45        }46      }47    }48  }49 50  bool isValid() const { return RI.isValid(); }51 52  MCRegister operator*() const {53    assert(SI.isValid() && "Cannot dereference an invalid iterator.");54    return *SI;55  }56 57  void advance() {58    // Assuming SI is valid.59    ++SI;60    if (SI.isValid())61      return;62 63    ++RRI;64    if (RRI.isValid()) {65      SI = MCSuperRegIterator(*RRI, MCRI, true);66      return;67    }68 69    ++RI;70    if (RI.isValid()) {71      RRI = MCRegUnitRootIterator(*RI, MCRI);72      SI = MCSuperRegIterator(*RRI, MCRI, true);73    }74  }75 76  MCRegAliasIteratorImpl &operator++() {77    assert(isValid() && "Cannot move off the end of the list.");78    do79      advance();80    while (isValid() && *SI == Reg);81    return *this;82  }83};84} // namespace85 86ArrayRef<MCPhysReg> MCRegisterInfo::getCachedAliasesOf(MCRegister R) const {87  auto &Aliases = RegAliasesCache[R.id()];88  if (!Aliases.empty())89    return Aliases;90 91  for (MCRegAliasIteratorImpl It(R, this); It.isValid(); ++It)92    Aliases.push_back((*It).id());93 94  sort(Aliases);95  Aliases.erase(unique(Aliases), Aliases.end());96  assert(!llvm::is_contained(Aliases, R) &&97         "MCRegAliasIteratorImpl includes Self!");98 99  // Always put "self" at the end, so the iterator can choose to ignore it.100  // For registers without aliases, it also serves as a sentinel value that101  // tells us to not recompute the alias set.102  Aliases.push_back(R.id());103  Aliases.shrink_to_fit();104  return Aliases;105}106 107MCRegister108MCRegisterInfo::getMatchingSuperReg(MCRegister Reg, unsigned SubIdx,109                                    const MCRegisterClass *RC) const {110  for (MCPhysReg Super : superregs(Reg))111    if (RC->contains(Super) && Reg == getSubReg(Super, SubIdx))112      return Super;113  return 0;114}115 116MCRegister MCRegisterInfo::getSubReg(MCRegister Reg, unsigned Idx) const {117  assert(Idx && Idx < getNumSubRegIndices() &&118         "This is not a subregister index");119  // Get a pointer to the corresponding SubRegIndices list. This list has the120  // name of each sub-register in the same order as MCSubRegIterator.121  const uint16_t *SRI = SubRegIndices + get(Reg).SubRegIndices;122  for (MCPhysReg Sub : subregs(Reg)) {123    if (*SRI == Idx)124      return Sub;125    ++SRI;126  }127  return 0;128}129 130unsigned MCRegisterInfo::getSubRegIndex(MCRegister Reg,131                                        MCRegister SubReg) const {132  assert(SubReg && SubReg < getNumRegs() && "This is not a register");133  // Get a pointer to the corresponding SubRegIndices list. This list has the134  // name of each sub-register in the same order as MCSubRegIterator.135  const uint16_t *SRI = SubRegIndices + get(Reg).SubRegIndices;136  for (MCPhysReg Sub : subregs(Reg)) {137    if (Sub == SubReg)138      return *SRI;139    ++SRI;140  }141  return 0;142}143 144int64_t MCRegisterInfo::getDwarfRegNum(MCRegister Reg, bool isEH) const {145  const DwarfLLVMRegPair *M = isEH ? EHL2DwarfRegs : L2DwarfRegs;146  unsigned Size = isEH ? EHL2DwarfRegsSize : L2DwarfRegsSize;147 148  if (!M)149    return -1;150  DwarfLLVMRegPair Key = {Reg.id(), 0};151  const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);152  if (I == M + Size || I->FromReg != Reg)153    return -1;154  // Consumers need to be able to detect -1 and -2, but at various points155  // the numbers move between unsigned and signed representations, as well as156  // between 32- and 64-bit representations. We need to convert first to int157  // before int64_t for proper sign handling.158  return int64_t(int(I->ToReg));159}160 161std::optional<MCRegister> MCRegisterInfo::getLLVMRegNum(uint64_t RegNum,162                                                        bool isEH) const {163  const DwarfLLVMRegPair *M = isEH ? EHDwarf2LRegs : Dwarf2LRegs;164  unsigned Size = isEH ? EHDwarf2LRegsSize : Dwarf2LRegsSize;165 166  if (!M)167    return std::nullopt;168  DwarfLLVMRegPair Key = {unsigned(RegNum), 0};169  const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);170  if (I != M + Size && I->FromReg == RegNum)171    return MCRegister::from(I->ToReg);172  return std::nullopt;173}174 175int64_t MCRegisterInfo::getDwarfRegNumFromDwarfEHRegNum(uint64_t RegNum) const {176  // On ELF platforms, DWARF EH register numbers are the same as DWARF177  // other register numbers.  On Darwin x86, they differ and so need to be178  // mapped.  The .cfi_* directives accept integer literals as well as179  // register names and should generate exactly what the assembly code180  // asked for, so there might be DWARF/EH register numbers that don't have181  // a corresponding LLVM register number at all.  So if we can't map the182  // EH register number to an LLVM register number, assume it's just a183  // valid DWARF register number as is.184  if (std::optional<MCRegister> LRegNum = getLLVMRegNum(RegNum, true)) {185    int DwarfRegNum = getDwarfRegNum(*LRegNum, false);186    if (DwarfRegNum == -1)187      return RegNum;188    else189      return DwarfRegNum;190  }191  return RegNum;192}193 194int MCRegisterInfo::getSEHRegNum(MCRegister Reg) const {195  const DenseMap<MCRegister, int>::const_iterator I = L2SEHRegs.find(Reg);196  if (I == L2SEHRegs.end())197    return (int)Reg.id();198  return I->second;199}200 201int MCRegisterInfo::getCodeViewRegNum(MCRegister Reg) const {202  if (L2CVRegs.empty())203    report_fatal_error("target does not implement codeview register mapping");204  const DenseMap<MCRegister, int>::const_iterator I = L2CVRegs.find(Reg);205  if (I == L2CVRegs.end())206    report_fatal_error("unknown codeview register " + (Reg.id() < getNumRegs()207                                                           ? getName(Reg)208                                                           : Twine(Reg.id())));209  return I->second;210}211 212bool MCRegisterInfo::regsOverlap(MCRegister RegA, MCRegister RegB) const {213  // Regunits are numerically ordered. Find a common unit.214  auto RangeA = regunits(RegA);215  MCRegUnitIterator IA = RangeA.begin(), EA = RangeA.end();216  auto RangeB = regunits(RegB);217  MCRegUnitIterator IB = RangeB.begin(), EB = RangeB.end();218  do {219    if (*IA == *IB)220      return true;221  } while (*IA < *IB ? ++IA != EA : ++IB != EB);222  return false;223}224 225bool MCRegisterInfo::isArtificialRegUnit(MCRegUnit Unit) const {226  for (MCRegUnitRootIterator Root(Unit, this); Root.isValid(); ++Root)227    if (isArtificial(*Root))228      return true;229  return false;230}231