Go to the documentation of this file.
28 class UnwindOpcodeStreamer {
37 void EmitByte(uint8_t elem) {
39 Pos = (((Pos ^ 0x3u) + 1) ^ 0x3u);
43 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 void EmitPersonalityIndex(
unsigned PI) {
53 "Invalid personality prefix");
58 void FillFinishOpcode() {
59 while (Pos < Vec.size())
74 if (RegSave & (1u << 4)) {
82 Mask &= ~(0xffffffe0u << Range);
86 if (UnmaskedReg == 0u) {
90 }
else if (UnmaskedReg == (1u << 14)) {
98 if ((RegSave & 0xfff0u) != 0)
102 if ((RegSave & 0x000fu) != 0)
110 for (
uint32_t Regs : {VFPRegSave & 0xffff0000u, VFPRegSave & 0x0000ffffu}) {
115 auto RangeLSB = RangeMSB - RangeLen;
117 int Opcode = RangeLSB >= 16
121 EmitInt16(Opcode | ((RangeLSB % 16) << 4) | (RangeLen - 1));
124 Regs &= ~(-1u << RangeLSB);
136 if (Offset > 0x200) {
139 size_t ULEBSize =
encodeULEB128((Offset - 0x204) >> 2, Buff + 1);
140 emitBytes(Buff, ULEBSize + 1);
141 }
else if (Offset > 0) {
142 if (Offset > 0x100) {
147 static_cast<uint8_t
>((Offset - 4) >> 2));
148 }
else if (Offset < 0) {
149 while (Offset < -0x100) {
154 static_cast<uint8_t
>(((-Offset) - 4) >> 2));
160 UnwindOpcodeStreamer OpStreamer(Result);
162 if (HasPersonality) {
165 size_t TotalSize = Ops.size() + 1;
166 size_t RoundUpSize = (TotalSize + 3) / 4 * 4;
167 Result.resize(RoundUpSize);
168 OpStreamer.EmitSize(RoundUpSize);
176 assert(Ops.size() <= 3 &&
"too many opcodes for __aeabi_unwind_cpp_pr0");
178 OpStreamer.EmitPersonalityIndex(PersonalityIndex);
181 size_t TotalSize = Ops.size() + 2;
182 size_t RoundUpSize = (TotalSize + 3) / 4 * 4;
183 Result.resize(RoundUpSize);
184 OpStreamer.EmitPersonalityIndex(PersonalityIndex);
185 OpStreamer.EmitSize(RoundUpSize);
190 for (
size_t i = OpBegins.size() - 1;
i > 0; --
i)
191 for (
size_t j = OpBegins[
i - 1],
end = OpBegins[
i];
j <
end; ++
j)
192 OpStreamer.EmitByte(Ops[
j]);
195 OpStreamer.FillFinishOpcode();
This is an optimization pass for GlobalISel generic memory operations.
@ UNWIND_OPCODE_POP_REG_RANGE_R4
Reg
All possible values of the reg field in the ModR/M byte.
const_iterator end(StringRef path)
Get end iterator over path.
@ UNWIND_OPCODE_INC_VSP_ULEB128
@ UNWIND_OPCODE_POP_REG_RANGE_R4_R14
unsigned countLeadingOnes(T Value, ZeroBehavior ZB=ZB_Width)
Count the number of ones from the most significant bit to the first zero bit.
@ UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ UNWIND_OPCODE_POP_REG_MASK
void Finalize(unsigned &PersonalityIndex, SmallVectorImpl< uint8_t > &Result)
Finalize the unwind opcode sequence for emitBytes()
@ UNWIND_OPCODE_POP_RA_AUTH_CODE
@ UNWIND_OPCODE_POP_REG_MASK_R4
unsigned countTrailingOnes(T Value, ZeroBehavior ZB=ZB_Width)
Count the number of ones from the least significant bit to the first zero bit.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void EmitSetSP(uint16_t Reg)
Emit unwind opcodes to copy address from source register to $sp.
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 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 EmitVFPRegSave(uint32_t VFPRegSave)
Emit unwind opcodes for .vsave directives.
@ UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD_D16
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
void Reset()
Reset the unwind opcode assembler.