29 class UnwindOpcodeStreamer {
38 void EmitByte(uint8_t elem) {
40 Pos = (((Pos ^ 0x3u) + 1) ^ 0x3u);
44 void EmitSize(
size_t Size) {
45 size_t SizeInWords = (Size + 3) / 4;
46 assert(SizeInWords <= 0x100u &&
47 "Only 256 additional words are allowed for unwind opcodes");
48 EmitByte(static_cast<uint8_t>(SizeInWords - 1));
52 void EmitPersonalityIndex(
unsigned PI) {
54 "Invalid personality prefix");
59 void FillFinishOpcode() {
60 while (Pos < Vec.
size())
72 if (RegSave & (1u << 4)) {
80 Mask &= ~(0xffffffe0u << Range);
83 uint32_t UnmaskedReg = RegSave & 0xfff0u & (~Mask);
84 if (UnmaskedReg == 0u) {
88 }
else if (UnmaskedReg == (1u << 14)) {
96 if ((RegSave & 0xfff0u) != 0)
100 if ((RegSave & 0x000fu) != 0)
108 for (
uint32_t Regs : {VFPRegSave & 0xffff0000u, VFPRegSave & 0x0000ffffu}) {
113 auto RangeLSB = RangeMSB - RangeLen;
115 int Opcode = RangeLSB >= 16
119 EmitInt16(Opcode | ((RangeLSB % 16) << 4) | (RangeLen - 1));
122 Regs &= ~(-1u << RangeLSB);
134 if (Offset > 0x200) {
137 size_t ULEBSize =
encodeULEB128((Offset - 0x204) >> 2, Buff + 1);
138 EmitBytes(Buff, ULEBSize + 1);
139 }
else if (Offset > 0) {
140 if (Offset > 0x100) {
145 static_cast<uint8_t>((Offset - 4) >> 2));
146 }
else if (Offset < 0) {
147 while (Offset < -0x100) {
152 static_cast<uint8_t>(((-Offset) - 4) >> 2));
158 UnwindOpcodeStreamer OpStreamer(Result);
160 if (HasPersonality) {
163 size_t TotalSize = Ops.size() + 1;
164 size_t RoundUpSize = (TotalSize + 3) / 4 * 4;
165 Result.
resize(RoundUpSize);
166 OpStreamer.EmitSize(RoundUpSize);
174 assert(Ops.size() <= 3 &&
"too many opcodes for __aeabi_unwind_cpp_pr0");
176 OpStreamer.EmitPersonalityIndex(PersonalityIndex);
179 size_t TotalSize = Ops.size() + 2;
180 size_t RoundUpSize = (TotalSize + 3) / 4 * 4;
181 Result.
resize(RoundUpSize);
182 OpStreamer.EmitPersonalityIndex(PersonalityIndex);
183 OpStreamer.EmitSize(RoundUpSize);
188 for (
size_t i = OpBegins.size() - 1; i > 0; --i)
189 for (
size_t j = OpBegins[i - 1],
end = OpBegins[i]; j <
end; ++j)
190 OpStreamer.EmitByte(Ops[j]);
193 OpStreamer.FillFinishOpcode();
const_iterator end(StringRef path)
Get end iterator over path.
This class represents lattice values for constants.
std::size_t countLeadingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the most significant bit to the least stopping at the first 1...
void Finalize(unsigned &PersonalityIndex, SmallVectorImpl< uint8_t > &Result)
Finalize the unwind opcode sequence for EmitBytes()
std::size_t countTrailingOnes(T Value, ZeroBehavior ZB=ZB_Width)
Count the number of ones from the least significant bit to the first zero bit.
void EmitSPOffset(int64_t Offset)
Emit unwind opcodes to add $sp with an offset.
void EmitRegSave(uint32_t RegSave)
Emit unwind opcodes for .save directives.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void EmitVFPRegSave(uint32_t VFPRegSave)
Emit unwind opcodes for .vsave directives.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
std::size_t countLeadingOnes(T Value, ZeroBehavior ZB=ZB_Width)
Count the number of ones from the most significant bit to the first zero bit.
void EmitSetSP(uint16_t Reg)
Emit unwind opcodes to copy address from source register to $sp.