27 class UnwindOpcodeStreamer {
37 inline void EmitByte(uint8_t elem) {
39 Pos = (((Pos ^ 0x3u) + 1) ^ 0x3u);
43 inline void EmitSize(
size_t Size) {
44 size_t SizeInWords = (Size + 3) / 4;
45 assert(SizeInWords <= 0x100u &&
46 "Only 256 additional words are allowed for unwind opcodes");
47 EmitByte(static_cast<uint8_t>(SizeInWords - 1));
51 inline void EmitPersonalityIndex(
unsigned PI) {
53 "Invalid personality prefix");
58 inline void FillFinishOpcode() {
59 while (Pos < Vec.size())
70 if (RegSave & (1u << 4)) {
75 uint32_t Mask = RegSave & 0xff0u;
78 Mask &= ~(0xffffffe0u << Range);
81 uint32_t UnmaskedReg = RegSave & 0xfff0u & (~Mask);
82 if (UnmaskedReg == 0u) {
86 }
else if (UnmaskedReg == (1u << 14)) {
94 if ((RegSave & 0xfff0u) != 0)
98 if ((RegSave & 0x000fu) != 0)
106 for (uint32_t Regs : {VFPRegSave & 0xffff0000u, VFPRegSave & 0x0000ffffu}) {
111 auto RangeLSB = RangeMSB - RangeLen;
113 int Opcode = RangeLSB >= 16
117 EmitInt16(Opcode | ((RangeLSB % 16) << 4) | (RangeLen - 1));
120 Regs &= ~(-1u << RangeLSB);
132 if (Offset > 0x200) {
135 size_t ULEBSize =
encodeULEB128((Offset - 0x204) >> 2, Buff + 1);
136 EmitBytes(Buff, ULEBSize + 1);
137 }
else if (Offset > 0) {
138 if (Offset > 0x100) {
143 static_cast<uint8_t>((Offset - 4) >> 2));
144 }
else if (Offset < 0) {
145 while (Offset < -0x100) {
150 static_cast<uint8_t>(((-Offset) - 4) >> 2));
157 UnwindOpcodeStreamer OpStreamer(Result);
159 if (HasPersonality) {
162 size_t TotalSize = Ops.
size() + 1;
163 size_t RoundUpSize = (TotalSize + 3) / 4 * 4;
164 Result.
resize(RoundUpSize);
165 OpStreamer.EmitSize(RoundUpSize);
173 assert(Ops.
size() <= 3 &&
"too many opcodes for __aeabi_unwind_cpp_pr0");
175 OpStreamer.EmitPersonalityIndex(PersonalityIndex);
178 size_t TotalSize = Ops.
size() + 2;
179 size_t RoundUpSize = (TotalSize + 3) / 4 * 4;
180 Result.
resize(RoundUpSize);
181 OpStreamer.EmitPersonalityIndex(PersonalityIndex);
182 OpStreamer.EmitSize(RoundUpSize);
187 for (
size_t i = OpBegins.
size() - 1; i > 0; --i)
188 for (
size_t j = OpBegins[i - 1],
end = OpBegins[i]; j <
end; ++j)
189 OpStreamer.EmitByte(Ops[j]);
192 OpStreamer.FillFinishOpcode();
const_iterator end(StringRef path)
Get end iterator over path.
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.
Reg
All possible values of the reg field in the ModR/M byte.
void Reset()
Reset the unwind opcode assembler.
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.
void EmitVFPRegSave(uint32_t VFPRegSave)
Emit unwind opcodes for .vsave directives.
void encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned Padding=0)
Utility function to encode a ULEB128 value to an output stream.
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.