28 class UnwindOpcodeStreamer {
38 inline void EmitByte(uint8_t elem) {
40 Pos = (((Pos ^ 0x3u) + 1) ^ 0x3u);
44 inline 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 inline void EmitPersonalityIndex(
unsigned PI) {
58 inline void FillFinishOpcode() {
59 while (Pos < Vec.size())
70 if (RegSave & (1u << 4)) {
76 uint32_t Mask = (1u << 4);
77 for (uint32_t
Bit = (1u << 5);
Bit < (1u << 12);
Bit <<= 1) {
78 if ((RegSave & Bit) == 0u)
85 uint32_t UnmaskedReg = RegSave & 0xfff0u & (~Mask);
86 if (UnmaskedReg == 0u) {
90 }
else if (UnmaskedReg == (1u << 14)) {
98 if ((RegSave & 0xfff0u) != 0)
102 if ((RegSave & 0x000fu) != 0)
111 uint32_t
Bit = 1u << (i - 1);
112 if ((VFPRegSave & Bit) == 0u) {
122 while (i > 16 && (VFPRegSave & Bit)) {
129 ((i - 16) << 4) | Range);
133 uint32_t
Bit = 1u << (i - 1);
134 if ((VFPRegSave & Bit) == 0u) {
144 while (i > 0 && (VFPRegSave & Bit)) {
161 if (Offset > 0x200) {
164 size_t ULEBSize =
encodeULEB128((Offset - 0x204) >> 2, Buff + 1);
165 EmitBytes(Buff, ULEBSize + 1);
166 }
else if (Offset > 0) {
167 if (Offset > 0x100) {
172 }
else if (Offset < 0) {
173 while (Offset < -0x100) {
178 static_cast<uint8_t>(((-Offset) - 4) >> 2));
185 UnwindOpcodeStreamer OpStreamer(Result);
187 if (HasPersonality) {
190 size_t TotalSize = Ops.
size() + 1;
191 size_t RoundUpSize = (TotalSize + 3) / 4 * 4;
192 Result.
resize(RoundUpSize);
193 OpStreamer.EmitSize(RoundUpSize);
195 if (Ops.
size() <= 3) {
199 OpStreamer.EmitPersonalityIndex(PersonalityIndex);
203 size_t TotalSize = Ops.
size() + 2;
204 size_t RoundUpSize = (TotalSize + 3) / 4 * 4;
205 Result.
resize(RoundUpSize);
206 OpStreamer.EmitPersonalityIndex(PersonalityIndex);
207 OpStreamer.EmitSize(RoundUpSize);
212 for (
size_t i = OpBegins.
size() - 1; i > 0; --i)
213 for (
size_t j = OpBegins[i - 1],
end = OpBegins[i]; j <
end; ++j)
214 OpStreamer.EmitByte(Ops[j]);
217 OpStreamer.FillFinishOpcode();
const_iterator end(StringRef path)
Get end iterator over path.
void Finalize(unsigned &PersonalityIndex, SmallVectorImpl< uint8_t > &Result)
Finalize the unwind opcode sequence for EmitBytes()
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.
void EmitSetSP(uint16_t Reg)
Emit unwind opcodes to copy address from source register to $sp.