ARMUnwindOpAsm.h revision 263508
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
24namespace llvm {
25
26class MCSymbol;
27
28class UnwindOpcodeAssembler {
29private:
30  llvm::SmallVector<uint8_t, 32> Ops;
31  llvm::SmallVector<unsigned, 8> OpBegins;
32  bool HasPersonality;
33
34public:
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
69private:
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
90