xref: /freebsd/contrib/llvm-project/llvm/lib/MC/MCRegisterInfo.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- MC/MCRegisterInfo.cpp - Target Register Description ----------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements MCRegisterInfo functions.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
140b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
150b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
160b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
170b57cec5SDimitry Andric #include <algorithm>
180b57cec5SDimitry Andric #include <cassert>
190b57cec5SDimitry Andric #include <cstdint>
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric using namespace llvm;
220b57cec5SDimitry Andric 
23*0fca6ea1SDimitry Andric namespace {
24*0fca6ea1SDimitry Andric /// MCRegAliasIterator enumerates all registers aliasing Reg.  This iterator
25*0fca6ea1SDimitry Andric /// does not guarantee any ordering or that entries are unique.
26*0fca6ea1SDimitry Andric class MCRegAliasIteratorImpl {
27*0fca6ea1SDimitry Andric private:
28*0fca6ea1SDimitry Andric   MCRegister Reg;
29*0fca6ea1SDimitry Andric   const MCRegisterInfo *MCRI;
30*0fca6ea1SDimitry Andric 
31*0fca6ea1SDimitry Andric   MCRegUnitIterator RI;
32*0fca6ea1SDimitry Andric   MCRegUnitRootIterator RRI;
33*0fca6ea1SDimitry Andric   MCSuperRegIterator SI;
34*0fca6ea1SDimitry Andric 
35*0fca6ea1SDimitry Andric public:
MCRegAliasIteratorImpl(MCRegister Reg,const MCRegisterInfo * MCRI)36*0fca6ea1SDimitry Andric   MCRegAliasIteratorImpl(MCRegister Reg, const MCRegisterInfo *MCRI)
37*0fca6ea1SDimitry Andric       : Reg(Reg), MCRI(MCRI) {
38*0fca6ea1SDimitry Andric 
39*0fca6ea1SDimitry Andric     // Initialize the iterators.
40*0fca6ea1SDimitry Andric     for (RI = MCRegUnitIterator(Reg, MCRI); RI.isValid(); ++RI) {
41*0fca6ea1SDimitry Andric       for (RRI = MCRegUnitRootIterator(*RI, MCRI); RRI.isValid(); ++RRI) {
42*0fca6ea1SDimitry Andric         for (SI = MCSuperRegIterator(*RRI, MCRI, true); SI.isValid(); ++SI) {
43*0fca6ea1SDimitry Andric           if (Reg != *SI)
44*0fca6ea1SDimitry Andric             return;
45*0fca6ea1SDimitry Andric         }
46*0fca6ea1SDimitry Andric       }
47*0fca6ea1SDimitry Andric     }
48*0fca6ea1SDimitry Andric   }
49*0fca6ea1SDimitry Andric 
isValid() const50*0fca6ea1SDimitry Andric   bool isValid() const { return RI.isValid(); }
51*0fca6ea1SDimitry Andric 
operator *() const52*0fca6ea1SDimitry Andric   MCRegister operator*() const {
53*0fca6ea1SDimitry Andric     assert(SI.isValid() && "Cannot dereference an invalid iterator.");
54*0fca6ea1SDimitry Andric     return *SI;
55*0fca6ea1SDimitry Andric   }
56*0fca6ea1SDimitry Andric 
advance()57*0fca6ea1SDimitry Andric   void advance() {
58*0fca6ea1SDimitry Andric     // Assuming SI is valid.
59*0fca6ea1SDimitry Andric     ++SI;
60*0fca6ea1SDimitry Andric     if (SI.isValid())
61*0fca6ea1SDimitry Andric       return;
62*0fca6ea1SDimitry Andric 
63*0fca6ea1SDimitry Andric     ++RRI;
64*0fca6ea1SDimitry Andric     if (RRI.isValid()) {
65*0fca6ea1SDimitry Andric       SI = MCSuperRegIterator(*RRI, MCRI, true);
66*0fca6ea1SDimitry Andric       return;
67*0fca6ea1SDimitry Andric     }
68*0fca6ea1SDimitry Andric 
69*0fca6ea1SDimitry Andric     ++RI;
70*0fca6ea1SDimitry Andric     if (RI.isValid()) {
71*0fca6ea1SDimitry Andric       RRI = MCRegUnitRootIterator(*RI, MCRI);
72*0fca6ea1SDimitry Andric       SI = MCSuperRegIterator(*RRI, MCRI, true);
73*0fca6ea1SDimitry Andric     }
74*0fca6ea1SDimitry Andric   }
75*0fca6ea1SDimitry Andric 
operator ++()76*0fca6ea1SDimitry Andric   MCRegAliasIteratorImpl &operator++() {
77*0fca6ea1SDimitry Andric     assert(isValid() && "Cannot move off the end of the list.");
78*0fca6ea1SDimitry Andric     do
79*0fca6ea1SDimitry Andric       advance();
80*0fca6ea1SDimitry Andric     while (isValid() && *SI == Reg);
81*0fca6ea1SDimitry Andric     return *this;
82*0fca6ea1SDimitry Andric   }
83*0fca6ea1SDimitry Andric };
84*0fca6ea1SDimitry Andric } // namespace
85*0fca6ea1SDimitry Andric 
getCachedAliasesOf(MCPhysReg R) const86*0fca6ea1SDimitry Andric ArrayRef<MCPhysReg> MCRegisterInfo::getCachedAliasesOf(MCPhysReg R) const {
87*0fca6ea1SDimitry Andric   auto &Aliases = RegAliasesCache[R];
88*0fca6ea1SDimitry Andric   if (!Aliases.empty())
89*0fca6ea1SDimitry Andric     return Aliases;
90*0fca6ea1SDimitry Andric 
91*0fca6ea1SDimitry Andric   for (MCRegAliasIteratorImpl It(R, this); It.isValid(); ++It)
92*0fca6ea1SDimitry Andric     Aliases.push_back(*It);
93*0fca6ea1SDimitry Andric 
94*0fca6ea1SDimitry Andric   sort(Aliases);
95*0fca6ea1SDimitry Andric   Aliases.erase(unique(Aliases), Aliases.end());
96*0fca6ea1SDimitry Andric   assert(none_of(Aliases, [&](auto &Cur) { return R == Cur; }) &&
97*0fca6ea1SDimitry Andric          "MCRegAliasIteratorImpl includes Self!");
98*0fca6ea1SDimitry Andric 
99*0fca6ea1SDimitry Andric   // Always put "self" at the end, so the iterator can choose to ignore it.
100*0fca6ea1SDimitry Andric   // For registers without aliases, it also serves as a sentinel value that
101*0fca6ea1SDimitry Andric   // tells us to not recompute the alias set.
102*0fca6ea1SDimitry Andric   Aliases.push_back(R);
103*0fca6ea1SDimitry Andric   Aliases.shrink_to_fit();
104*0fca6ea1SDimitry Andric   return Aliases;
105*0fca6ea1SDimitry Andric }
106*0fca6ea1SDimitry Andric 
1078bcb0991SDimitry Andric MCRegister
getMatchingSuperReg(MCRegister Reg,unsigned SubIdx,const MCRegisterClass * RC) const1088bcb0991SDimitry Andric MCRegisterInfo::getMatchingSuperReg(MCRegister Reg, unsigned SubIdx,
1090b57cec5SDimitry Andric                                     const MCRegisterClass *RC) const {
11006c3fb27SDimitry Andric   for (MCPhysReg Super : superregs(Reg))
11106c3fb27SDimitry Andric     if (RC->contains(Super) && Reg == getSubReg(Super, SubIdx))
11206c3fb27SDimitry Andric       return Super;
1130b57cec5SDimitry Andric   return 0;
1140b57cec5SDimitry Andric }
1150b57cec5SDimitry Andric 
getSubReg(MCRegister Reg,unsigned Idx) const1168bcb0991SDimitry Andric MCRegister MCRegisterInfo::getSubReg(MCRegister Reg, unsigned Idx) const {
1170b57cec5SDimitry Andric   assert(Idx && Idx < getNumSubRegIndices() &&
1180b57cec5SDimitry Andric          "This is not a subregister index");
1190b57cec5SDimitry Andric   // Get a pointer to the corresponding SubRegIndices list. This list has the
1200b57cec5SDimitry Andric   // name of each sub-register in the same order as MCSubRegIterator.
1210b57cec5SDimitry Andric   const uint16_t *SRI = SubRegIndices + get(Reg).SubRegIndices;
12206c3fb27SDimitry Andric   for (MCPhysReg Sub : subregs(Reg)) {
1230b57cec5SDimitry Andric     if (*SRI == Idx)
12406c3fb27SDimitry Andric       return Sub;
12506c3fb27SDimitry Andric     ++SRI;
12606c3fb27SDimitry Andric   }
1270b57cec5SDimitry Andric   return 0;
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric 
getSubRegIndex(MCRegister Reg,MCRegister SubReg) const1308bcb0991SDimitry Andric unsigned MCRegisterInfo::getSubRegIndex(MCRegister Reg,
1318bcb0991SDimitry Andric                                         MCRegister SubReg) const {
1320b57cec5SDimitry Andric   assert(SubReg && SubReg < getNumRegs() && "This is not a register");
1330b57cec5SDimitry Andric   // Get a pointer to the corresponding SubRegIndices list. This list has the
1340b57cec5SDimitry Andric   // name of each sub-register in the same order as MCSubRegIterator.
1350b57cec5SDimitry Andric   const uint16_t *SRI = SubRegIndices + get(Reg).SubRegIndices;
13606c3fb27SDimitry Andric   for (MCPhysReg Sub : subregs(Reg)) {
13706c3fb27SDimitry Andric     if (Sub == SubReg)
1380b57cec5SDimitry Andric       return *SRI;
13906c3fb27SDimitry Andric     ++SRI;
14006c3fb27SDimitry Andric   }
1410b57cec5SDimitry Andric   return 0;
1420b57cec5SDimitry Andric }
1430b57cec5SDimitry Andric 
getDwarfRegNum(MCRegister RegNum,bool isEH) const1448bcb0991SDimitry Andric int MCRegisterInfo::getDwarfRegNum(MCRegister RegNum, bool isEH) const {
1450b57cec5SDimitry Andric   const DwarfLLVMRegPair *M = isEH ? EHL2DwarfRegs : L2DwarfRegs;
1460b57cec5SDimitry Andric   unsigned Size = isEH ? EHL2DwarfRegsSize : L2DwarfRegsSize;
1470b57cec5SDimitry Andric 
1480b57cec5SDimitry Andric   if (!M)
1490b57cec5SDimitry Andric     return -1;
1500b57cec5SDimitry Andric   DwarfLLVMRegPair Key = { RegNum, 0 };
1510b57cec5SDimitry Andric   const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);
1520b57cec5SDimitry Andric   if (I == M+Size || I->FromReg != RegNum)
1530b57cec5SDimitry Andric     return -1;
1540b57cec5SDimitry Andric   return I->ToReg;
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric 
getLLVMRegNum(unsigned RegNum,bool isEH) const157bdd1243dSDimitry Andric std::optional<unsigned> MCRegisterInfo::getLLVMRegNum(unsigned RegNum,
1588bcb0991SDimitry Andric                                                       bool isEH) const {
1590b57cec5SDimitry Andric   const DwarfLLVMRegPair *M = isEH ? EHDwarf2LRegs : Dwarf2LRegs;
1600b57cec5SDimitry Andric   unsigned Size = isEH ? EHDwarf2LRegsSize : Dwarf2LRegsSize;
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric   if (!M)
163bdd1243dSDimitry Andric     return std::nullopt;
1640b57cec5SDimitry Andric   DwarfLLVMRegPair Key = { RegNum, 0 };
1650b57cec5SDimitry Andric   const DwarfLLVMRegPair *I = std::lower_bound(M, M+Size, Key);
1668bcb0991SDimitry Andric   if (I != M + Size && I->FromReg == RegNum)
1670b57cec5SDimitry Andric     return I->ToReg;
168bdd1243dSDimitry Andric   return std::nullopt;
1690b57cec5SDimitry Andric }
1700b57cec5SDimitry Andric 
getDwarfRegNumFromDwarfEHRegNum(unsigned RegNum) const1710b57cec5SDimitry Andric int MCRegisterInfo::getDwarfRegNumFromDwarfEHRegNum(unsigned RegNum) const {
1720b57cec5SDimitry Andric   // On ELF platforms, DWARF EH register numbers are the same as DWARF
1730b57cec5SDimitry Andric   // other register numbers.  On Darwin x86, they differ and so need to be
1740b57cec5SDimitry Andric   // mapped.  The .cfi_* directives accept integer literals as well as
1750b57cec5SDimitry Andric   // register names and should generate exactly what the assembly code
1760b57cec5SDimitry Andric   // asked for, so there might be DWARF/EH register numbers that don't have
1770b57cec5SDimitry Andric   // a corresponding LLVM register number at all.  So if we can't map the
1780b57cec5SDimitry Andric   // EH register number to an LLVM register number, assume it's just a
1790b57cec5SDimitry Andric   // valid DWARF register number as is.
18006c3fb27SDimitry Andric   if (std::optional<unsigned> LRegNum = getLLVMRegNum(RegNum, true)) {
18106c3fb27SDimitry Andric     int DwarfRegNum = getDwarfRegNum(*LRegNum, false);
18206c3fb27SDimitry Andric     if (DwarfRegNum == -1)
18306c3fb27SDimitry Andric       return RegNum;
18406c3fb27SDimitry Andric     else
18506c3fb27SDimitry Andric       return DwarfRegNum;
18606c3fb27SDimitry Andric   }
1870b57cec5SDimitry Andric   return RegNum;
1880b57cec5SDimitry Andric }
1890b57cec5SDimitry Andric 
getSEHRegNum(MCRegister RegNum) const1908bcb0991SDimitry Andric int MCRegisterInfo::getSEHRegNum(MCRegister RegNum) const {
1918bcb0991SDimitry Andric   const DenseMap<MCRegister, int>::const_iterator I = L2SEHRegs.find(RegNum);
1920b57cec5SDimitry Andric   if (I == L2SEHRegs.end()) return (int)RegNum;
1930b57cec5SDimitry Andric   return I->second;
1940b57cec5SDimitry Andric }
1950b57cec5SDimitry Andric 
getCodeViewRegNum(MCRegister RegNum) const1968bcb0991SDimitry Andric int MCRegisterInfo::getCodeViewRegNum(MCRegister RegNum) const {
1970b57cec5SDimitry Andric   if (L2CVRegs.empty())
1980b57cec5SDimitry Andric     report_fatal_error("target does not implement codeview register mapping");
1998bcb0991SDimitry Andric   const DenseMap<MCRegister, int>::const_iterator I = L2CVRegs.find(RegNum);
2000b57cec5SDimitry Andric   if (I == L2CVRegs.end())
2010b57cec5SDimitry Andric     report_fatal_error("unknown codeview register " + (RegNum < getNumRegs()
2020b57cec5SDimitry Andric                                                            ? getName(RegNum)
2030b57cec5SDimitry Andric                                                            : Twine(RegNum)));
2040b57cec5SDimitry Andric   return I->second;
2050b57cec5SDimitry Andric }
20681ad6265SDimitry Andric 
regsOverlap(MCRegister RegA,MCRegister RegB) const20781ad6265SDimitry Andric bool MCRegisterInfo::regsOverlap(MCRegister RegA, MCRegister RegB) const {
20881ad6265SDimitry Andric   // Regunits are numerically ordered. Find a common unit.
20906c3fb27SDimitry Andric   auto RangeA = regunits(RegA);
21006c3fb27SDimitry Andric   MCRegUnitIterator IA = RangeA.begin(), EA = RangeA.end();
21106c3fb27SDimitry Andric   auto RangeB = regunits(RegB);
21206c3fb27SDimitry Andric   MCRegUnitIterator IB = RangeB.begin(), EB = RangeB.end();
21381ad6265SDimitry Andric   do {
21406c3fb27SDimitry Andric     if (*IA == *IB)
21581ad6265SDimitry Andric       return true;
21606c3fb27SDimitry Andric   } while (*IA < *IB ? ++IA != EA : ++IB != EB);
21781ad6265SDimitry Andric   return false;
21881ad6265SDimitry Andric }
219