]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / lib / Target / ARM / MCTargetDesc / ARMUnwindOpAsm.h
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 ARM_UNWIND_OP_ASM_H
16 #define ARM_UNWIND_OP_ASM_H
17
18 #include "ARMUnwindOp.h"
19
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/Support/DataTypes.h"
23
24 namespace llvm {
25
26 class MCSymbol;
27
28 class UnwindOpcodeAssembler {
29 private:
30   llvm::SmallVector<uint8_t, 8> Ops;
31
32   unsigned Offset;
33   unsigned PersonalityIndex;
34   bool HasPersonality;
35
36   enum {
37     // The number of bytes to be preserved for the size and personality index
38     // prefix of unwind opcodes.
39     NUM_PRESERVED_PREFIX_BUF = 2
40   };
41
42 public:
43   UnwindOpcodeAssembler()
44       : Ops(NUM_PRESERVED_PREFIX_BUF), Offset(NUM_PRESERVED_PREFIX_BUF),
45         PersonalityIndex(NUM_PERSONALITY_INDEX), HasPersonality(0) {
46   }
47
48   /// Reset the unwind opcode assembler.
49   void Reset() {
50     Ops.resize(NUM_PRESERVED_PREFIX_BUF);
51     Offset = NUM_PRESERVED_PREFIX_BUF;
52     PersonalityIndex = NUM_PERSONALITY_INDEX;
53     HasPersonality = 0;
54   }
55
56   /// Get the size of the payload (including the size byte)
57   size_t size() const {
58     return Ops.size() - Offset;
59   }
60
61   /// Get the beginning of the payload
62   const uint8_t *begin() const {
63     return Ops.begin() + Offset;
64   }
65
66   /// Get the payload
67   StringRef data() const {
68     return StringRef(reinterpret_cast<const char *>(begin()), size());
69   }
70
71   /// Set the personality index
72   void setPersonality(const MCSymbol *Per) {
73     HasPersonality = 1;
74   }
75
76   /// Get the personality index
77   unsigned getPersonalityIndex() const {
78     return PersonalityIndex;
79   }
80
81   /// Emit unwind opcodes for .save directives
82   void EmitRegSave(uint32_t RegSave);
83
84   /// Emit unwind opcodes for .vsave directives
85   void EmitVFPRegSave(uint32_t VFPRegSave);
86
87   /// Emit unwind opcodes for .setfp directives
88   void EmitSetFP(uint16_t FPReg);
89
90   /// Emit unwind opcodes to update stack pointer
91   void EmitSPOffset(int64_t Offset);
92
93   /// Finalize the unwind opcode sequence for EmitBytes()
94   void Finalize();
95
96 private:
97   /// Get the size of the opcodes in bytes.
98   size_t getOpcodeSize() const {
99     return Ops.size() - NUM_PRESERVED_PREFIX_BUF;
100   }
101
102   /// Add the length prefix to the payload
103   void AddOpcodeSizePrefix(size_t Pos);
104
105   /// Add personality index prefix in some compact format
106   void AddPersonalityIndexPrefix(size_t Pos, unsigned PersonalityIndex);
107
108   /// Fill the words with finish opcode if it is not aligned
109   void EmitFinishOpcodes();
110 };
111
112 } // namespace llvm
113
114 #endif // ARM_UNWIND_OP_ASM_H