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