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: 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 50*0fca6ea1SDimitry Andric bool isValid() const { return RI.isValid(); } 51*0fca6ea1SDimitry Andric 52*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 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 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 86*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 1088bcb0991SDimitry 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 1168bcb0991SDimitry 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 1308bcb0991SDimitry 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 1448bcb0991SDimitry 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 157bdd1243dSDimitry 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 1710b57cec5SDimitry 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 1908bcb0991SDimitry 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 1968bcb0991SDimitry 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 20781ad6265SDimitry 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