]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/lib/Target/ARM/MCTargetDesc/ARMUnwindOpAsm.h
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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, 32> Ops;
31   llvm::SmallVector<unsigned, 8> OpBegins;
32   bool HasPersonality;
33
34 public:
35   UnwindOpcodeAssembler()
36       : HasPersonality(0) {
37     OpBegins.push_back(0);
38   }
39
40   /// Reset the unwind opcode assembler.
41   void Reset() {
42     Ops.clear();
43     OpBegins.clear();
44     OpBegins.push_back(0);
45     HasPersonality = 0;
46   }
47
48   /// Set the personality index
49   void setPersonality(const MCSymbol *Per) {
50     HasPersonality = 1;
51   }
52
53   /// Emit unwind opcodes for .save directives
54   void EmitRegSave(uint32_t RegSave);
55
56   /// Emit unwind opcodes for .vsave directives
57   void EmitVFPRegSave(uint32_t VFPRegSave);
58
59   /// Emit unwind opcodes to copy address from source register to $sp.
60   void EmitSetSP(uint16_t Reg);
61
62   /// Emit unwind opcodes to add $sp with an offset.
63   void EmitSPOffset(int64_t Offset);
64
65   /// Finalize the unwind opcode sequence for EmitBytes()
66   void Finalize(unsigned &PersonalityIndex,
67                 SmallVectorImpl<uint8_t> &Result);
68
69 private:
70   void EmitInt8(unsigned Opcode) {
71     Ops.push_back(Opcode & 0xff);
72     OpBegins.push_back(OpBegins.back() + 1);
73   }
74
75   void EmitInt16(unsigned Opcode) {
76     Ops.push_back((Opcode >> 8) & 0xff);
77     Ops.push_back(Opcode & 0xff);
78     OpBegins.push_back(OpBegins.back() + 2);
79   }
80
81   void EmitBytes(const uint8_t *Opcode, size_t Size) {
82     Ops.insert(Ops.end(), Opcode, Opcode + Size);
83     OpBegins.push_back(OpBegins.back() + Size);
84   }
85 };
86
87 } // namespace llvm
88
89 #endif // ARM_UNWIND_OP_ASM_H