LLVM: lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

18#include

19

20using namespace llvm;

21

22namespace {

23

24

25

26

27

28 class UnwindOpcodeStreamer {

29 private:

30 SmallVectorImpl<uint8_t> &Vec;

31 size_t Pos = 3;

32

33 public:

34 UnwindOpcodeStreamer(SmallVectorImpl<uint8_t> &V) : Vec(V) {}

35

36

37 void EmitByte(uint8_t elem) {

38 Vec[Pos] = elem;

39 Pos = (((Pos ^ 0x3u) + 1) ^ 0x3u);

40 }

41

42

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));

48 }

49

50

51 void EmitPersonalityIndex(unsigned PI) {

53 "Invalid personality prefix");

55 }

56

57

58 void FillFinishOpcode() {

59 while (Pos < Vec.size())

61 }

62 };

63

64}

65

67 if (RegSave == 0u) {

68

70 return;

71 }

72

73

74 if (RegSave & (1u << 4)) {

75

76

77

78

79 uint32_t Mask = RegSave & 0xff0u;

81

82 Mask &= ~(0xffffffe0u << Range);

83

84

85 uint32_t UnmaskedReg = RegSave & 0xfff0u & (~Mask);

86 if (UnmaskedReg == 0u) {

87

89 RegSave &= 0x000fu;

90 } else if (UnmaskedReg == (1u << 14)) {

91

93 RegSave &= 0x000fu;

94 }

95 }

96

97

98 if ((RegSave & 0xfff0u) != 0)

100

101

102 if ((RegSave & 0x000fu) != 0)

104}

105

106

108

109

110 for (uint32_t Regs : {VFPRegSave & 0xffff0000u, VFPRegSave & 0x0000ffffu}) {

111 while (Regs) {

112

115 auto RangeLSB = RangeMSB - RangeLen;

116

117 int Opcode = RangeLSB >= 16

120

121 EmitInt16(Opcode | ((RangeLSB % 16) << 4) | (RangeLen - 1));

122

123

124 Regs &= ~(-1u << RangeLSB);

125 }

126 }

127}

128

129

133

134

136 if (Offset > 0x200) {

140 emitBytes(Buff, ULEBSize + 1);

141 } else if (Offset > 0) {

142 if (Offset > 0x100) {

145 }

148 } else if (Offset < 0) {

149 while (Offset < -0x100) {

152 }

155 }

156}

157

160 UnwindOpcodeStreamer OpStreamer(Result);

161

162 if (HasPersonality) {

163

165 size_t TotalSize = Ops.size() + 1;

166 size_t RoundUpSize = (TotalSize + 3) / 4 * 4;

167 Result.resize(RoundUpSize);

168 OpStreamer.EmitSize(RoundUpSize);

169 } else {

170

175

176 assert(Ops.size() <= 3 && "too many opcodes for __aeabi_unwind_cpp_pr0");

177 Result.resize(4);

178 OpStreamer.EmitPersonalityIndex(PersonalityIndex);

179 } else {

180

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);

186 }

187 }

188

189

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]);

193

194

195 OpStreamer.FillFinishOpcode();

196

197

199}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))

This file implements the C++20 header.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void EmitSetSP(uint16_t Reg)

Emit unwind opcodes to copy address from source register to $sp.

Definition ARMUnwindOpAsm.cpp:130

void EmitVFPRegSave(uint32_t VFPRegSave)

Emit unwind opcodes for .vsave directives.

Definition ARMUnwindOpAsm.cpp:107

void EmitRegSave(uint32_t RegSave)

Emit unwind opcodes for .save directives.

Definition ARMUnwindOpAsm.cpp:66

void EmitSPOffset(int64_t Offset)

Emit unwind opcodes to add $sp with an offset.

Definition ARMUnwindOpAsm.cpp:135

void Reset()

Reset the unwind opcode assembler.

void Finalize(unsigned &PersonalityIndex, SmallVectorImpl< uint8_t > &Result)

Finalize the unwind opcode sequence for emitBytes()

Definition ARMUnwindOpAsm.cpp:158

@ UNWIND_OPCODE_POP_REG_RANGE_R4

@ UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD_D16

@ UNWIND_OPCODE_POP_REG_MASK

@ UNWIND_OPCODE_INC_VSP_ULEB128

@ UNWIND_OPCODE_POP_REG_RANGE_R4_R14

@ UNWIND_OPCODE_POP_RA_AUTH_CODE

@ UNWIND_OPCODE_POP_VFP_REG_RANGE_FSTMFDD

@ UNWIND_OPCODE_POP_REG_MASK_R4

This is an optimization pass for GlobalISel generic memory operations.

int countr_one(T Value)

Count the number of ones from the least significant bit to the first zero bit.

int bit_width(T Value)

Returns the number of bits needed to represent Value if Value is nonzero.

int countl_one(T Value)

Count the number of ones from the most significant bit to the first zero bit.

unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)

Utility function to encode a ULEB128 value to an output stream.