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-exception |
6 | // |
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 | |
21 | using namespace llvm; |
22 | |
23 | MCRegister |
24 | MCRegisterInfo::getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, |
25 | const MCRegisterClass *RC) const { |
26 | for (MCPhysReg Super : superregs(Reg)) |
27 | if (RC->contains(Reg: Super) && Reg == getSubReg(Reg: Super, Idx: SubIdx)) |
28 | return Super; |
29 | return 0; |
30 | } |
31 | |
32 | MCRegister MCRegisterInfo::getSubReg(MCRegister Reg, unsigned Idx) const { |
33 | assert(Idx && Idx < getNumSubRegIndices() && |
34 | "This is not a subregister index" ); |
35 | // Get a pointer to the corresponding SubRegIndices list. This list has the |
36 | // name of each sub-register in the same order as MCSubRegIterator. |
37 | const uint16_t *SRI = SubRegIndices + get(RegNo: Reg).SubRegIndices; |
38 | for (MCPhysReg Sub : subregs(Reg)) { |
39 | if (*SRI == Idx) |
40 | return Sub; |
41 | ++SRI; |
42 | } |
43 | return 0; |
44 | } |
45 | |
46 | unsigned MCRegisterInfo::getSubRegIndex(MCRegister Reg, |
47 | MCRegister SubReg) const { |
48 | assert(SubReg && SubReg < getNumRegs() && "This is not a register" ); |
49 | // Get a pointer to the corresponding SubRegIndices list. This list has the |
50 | // name of each sub-register in the same order as MCSubRegIterator. |
51 | const uint16_t *SRI = SubRegIndices + get(RegNo: Reg).SubRegIndices; |
52 | for (MCPhysReg Sub : subregs(Reg)) { |
53 | if (Sub == SubReg) |
54 | return *SRI; |
55 | ++SRI; |
56 | } |
57 | return 0; |
58 | } |
59 | |
60 | unsigned MCRegisterInfo::getSubRegIdxSize(unsigned Idx) const { |
61 | assert(Idx && Idx < getNumSubRegIndices() && |
62 | "This is not a subregister index" ); |
63 | return SubRegIdxRanges[Idx].Size; |
64 | } |
65 | |
66 | unsigned MCRegisterInfo::getSubRegIdxOffset(unsigned Idx) const { |
67 | assert(Idx && Idx < getNumSubRegIndices() && |
68 | "This is not a subregister index" ); |
69 | return SubRegIdxRanges[Idx].Offset; |
70 | } |
71 | |
72 | int MCRegisterInfo::getDwarfRegNum(MCRegister RegNum, bool isEH) const { |
73 | const DwarfLLVMRegPair *M = isEH ? EHL2DwarfRegs : L2DwarfRegs; |
74 | unsigned Size = isEH ? EHL2DwarfRegsSize : L2DwarfRegsSize; |
75 | |
76 | if (!M) |
77 | return -1; |
78 | DwarfLLVMRegPair Key = { .FromReg: RegNum, .ToReg: 0 }; |
79 | const DwarfLLVMRegPair *I = std::lower_bound(first: M, last: M+Size, val: Key); |
80 | if (I == M+Size || I->FromReg != RegNum) |
81 | return -1; |
82 | return I->ToReg; |
83 | } |
84 | |
85 | std::optional<unsigned> MCRegisterInfo::getLLVMRegNum(unsigned RegNum, |
86 | bool isEH) const { |
87 | const DwarfLLVMRegPair *M = isEH ? EHDwarf2LRegs : Dwarf2LRegs; |
88 | unsigned Size = isEH ? EHDwarf2LRegsSize : Dwarf2LRegsSize; |
89 | |
90 | if (!M) |
91 | return std::nullopt; |
92 | DwarfLLVMRegPair Key = { .FromReg: RegNum, .ToReg: 0 }; |
93 | const DwarfLLVMRegPair *I = std::lower_bound(first: M, last: M+Size, val: Key); |
94 | if (I != M + Size && I->FromReg == RegNum) |
95 | return I->ToReg; |
96 | return std::nullopt; |
97 | } |
98 | |
99 | int MCRegisterInfo::getDwarfRegNumFromDwarfEHRegNum(unsigned RegNum) const { |
100 | // On ELF platforms, DWARF EH register numbers are the same as DWARF |
101 | // other register numbers. On Darwin x86, they differ and so need to be |
102 | // mapped. The .cfi_* directives accept integer literals as well as |
103 | // register names and should generate exactly what the assembly code |
104 | // asked for, so there might be DWARF/EH register numbers that don't have |
105 | // a corresponding LLVM register number at all. So if we can't map the |
106 | // EH register number to an LLVM register number, assume it's just a |
107 | // valid DWARF register number as is. |
108 | if (std::optional<unsigned> LRegNum = getLLVMRegNum(RegNum, isEH: true)) { |
109 | int DwarfRegNum = getDwarfRegNum(RegNum: *LRegNum, isEH: false); |
110 | if (DwarfRegNum == -1) |
111 | return RegNum; |
112 | else |
113 | return DwarfRegNum; |
114 | } |
115 | return RegNum; |
116 | } |
117 | |
118 | int MCRegisterInfo::getSEHRegNum(MCRegister RegNum) const { |
119 | const DenseMap<MCRegister, int>::const_iterator I = L2SEHRegs.find(Val: RegNum); |
120 | if (I == L2SEHRegs.end()) return (int)RegNum; |
121 | return I->second; |
122 | } |
123 | |
124 | int MCRegisterInfo::getCodeViewRegNum(MCRegister RegNum) const { |
125 | if (L2CVRegs.empty()) |
126 | report_fatal_error(reason: "target does not implement codeview register mapping" ); |
127 | const DenseMap<MCRegister, int>::const_iterator I = L2CVRegs.find(Val: RegNum); |
128 | if (I == L2CVRegs.end()) |
129 | report_fatal_error(reason: "unknown codeview register " + (RegNum < getNumRegs() |
130 | ? getName(RegNo: RegNum) |
131 | : Twine(RegNum))); |
132 | return I->second; |
133 | } |
134 | |
135 | bool MCRegisterInfo::regsOverlap(MCRegister RegA, MCRegister RegB) const { |
136 | // Regunits are numerically ordered. Find a common unit. |
137 | auto RangeA = regunits(Reg: RegA); |
138 | MCRegUnitIterator IA = RangeA.begin(), EA = RangeA.end(); |
139 | auto RangeB = regunits(Reg: RegB); |
140 | MCRegUnitIterator IB = RangeB.begin(), EB = RangeB.end(); |
141 | do { |
142 | if (*IA == *IB) |
143 | return true; |
144 | } while (*IA < *IB ? ++IA != EA : ++IB != EB); |
145 | return false; |
146 | } |
147 | |