Line data Source code
1 : //===-- ARMUnwindOpAsm.h - ARM Unwind Opcodes Assembler ---------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file declares the unwind opcode assmebler for ARM exception handling
11 : // table.
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H
16 : #define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H
17 :
18 : #include "llvm/ADT/SmallVector.h"
19 : #include <cstddef>
20 : #include <cstdint>
21 :
22 : namespace llvm {
23 :
24 : class MCSymbol;
25 :
26 : class UnwindOpcodeAssembler {
27 : private:
28 : SmallVector<uint8_t, 32> Ops;
29 : SmallVector<unsigned, 8> OpBegins;
30 : bool HasPersonality = false;
31 :
32 : public:
33 422 : UnwindOpcodeAssembler() {
34 422 : OpBegins.push_back(0);
35 : }
36 :
37 : /// Reset the unwind opcode assembler.
38 : void Reset() {
39 : Ops.clear();
40 : OpBegins.clear();
41 1531 : OpBegins.push_back(0);
42 1531 : HasPersonality = false;
43 : }
44 :
45 : /// Set the personality
46 0 : void setPersonality(const MCSymbol *Per) {
47 69 : HasPersonality = true;
48 0 : }
49 :
50 : /// Emit unwind opcodes for .save directives
51 : void EmitRegSave(uint32_t RegSave);
52 :
53 : /// Emit unwind opcodes for .vsave directives
54 : void EmitVFPRegSave(uint32_t VFPRegSave);
55 :
56 : /// Emit unwind opcodes to copy address from source register to $sp.
57 : void EmitSetSP(uint16_t Reg);
58 :
59 : /// Emit unwind opcodes to add $sp with an offset.
60 : void EmitSPOffset(int64_t Offset);
61 :
62 : /// Emit unwind raw opcodes
63 53 : void EmitRaw(const SmallVectorImpl<uint8_t> &Opcodes) {
64 106 : Ops.insert(Ops.end(), Opcodes.begin(), Opcodes.end());
65 106 : OpBegins.push_back(OpBegins.back() + Opcodes.size());
66 53 : }
67 :
68 : /// Finalize the unwind opcode sequence for EmitBytes()
69 : void Finalize(unsigned &PersonalityIndex,
70 : SmallVectorImpl<uint8_t> &Result);
71 :
72 : private:
73 483 : void EmitInt8(unsigned Opcode) {
74 483 : Ops.push_back(Opcode & 0xff);
75 966 : OpBegins.push_back(OpBegins.back() + 1);
76 483 : }
77 :
78 273 : void EmitInt16(unsigned Opcode) {
79 273 : Ops.push_back((Opcode >> 8) & 0xff);
80 273 : Ops.push_back(Opcode & 0xff);
81 546 : OpBegins.push_back(OpBegins.back() + 2);
82 273 : }
83 :
84 137 : void EmitBytes(const uint8_t *Opcode, size_t Size) {
85 274 : Ops.insert(Ops.end(), Opcode, Opcode + Size);
86 274 : OpBegins.push_back(OpBegins.back() + Size);
87 137 : }
88 : };
89 :
90 : } // end namespace llvm
91 :
92 : #endif // LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H
|