blob: a824ef398f1de729daf11a91e5c44564725cd100 [file] [log] [blame]
Logan Chiend8bb4b72013-04-16 12:02:21 +00001//===-- 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
Logan Chiend8bb4b72013-04-16 12:02:21 +000018#include "llvm/ADT/SmallVector.h"
19#include "llvm/ADT/StringRef.h"
Saleem Abdulrasoolb961c992014-01-06 00:15:00 +000020#include "llvm/Support/ARMEHABI.h"
Logan Chiend8bb4b72013-04-16 12:02:21 +000021#include "llvm/Support/DataTypes.h"
22
23namespace llvm {
24
25class MCSymbol;
26
27class UnwindOpcodeAssembler {
28private:
Logan Chien325823a2013-06-09 12:22:30 +000029 llvm::SmallVector<uint8_t, 32> Ops;
30 llvm::SmallVector<unsigned, 8> OpBegins;
Logan Chiend8bb4b72013-04-16 12:02:21 +000031 bool HasPersonality;
32
Logan Chiend8bb4b72013-04-16 12:02:21 +000033public:
34 UnwindOpcodeAssembler()
Logan Chien325823a2013-06-09 12:22:30 +000035 : HasPersonality(0) {
36 OpBegins.push_back(0);
Logan Chiend8bb4b72013-04-16 12:02:21 +000037 }
38
39 /// Reset the unwind opcode assembler.
40 void Reset() {
Logan Chien325823a2013-06-09 12:22:30 +000041 Ops.clear();
42 OpBegins.clear();
43 OpBegins.push_back(0);
Logan Chiend8bb4b72013-04-16 12:02:21 +000044 HasPersonality = 0;
45 }
46
Logan Chiend8bb4b72013-04-16 12:02:21 +000047 /// Set the personality index
48 void setPersonality(const MCSymbol *Per) {
49 HasPersonality = 1;
50 }
51
Logan Chiend8bb4b72013-04-16 12:02:21 +000052 /// Emit unwind opcodes for .save directives
53 void EmitRegSave(uint32_t RegSave);
54
55 /// Emit unwind opcodes for .vsave directives
56 void EmitVFPRegSave(uint32_t VFPRegSave);
57
Logan Chien325823a2013-06-09 12:22:30 +000058 /// Emit unwind opcodes to copy address from source register to $sp.
59 void EmitSetSP(uint16_t Reg);
Logan Chiend8bb4b72013-04-16 12:02:21 +000060
Logan Chien325823a2013-06-09 12:22:30 +000061 /// Emit unwind opcodes to add $sp with an offset.
Logan Chiend8bb4b72013-04-16 12:02:21 +000062 void EmitSPOffset(int64_t Offset);
63
64 /// Finalize the unwind opcode sequence for EmitBytes()
Logan Chien325823a2013-06-09 12:22:30 +000065 void Finalize(unsigned &PersonalityIndex,
66 SmallVectorImpl<uint8_t> &Result);
Logan Chiend8bb4b72013-04-16 12:02:21 +000067
68private:
Logan Chien325823a2013-06-09 12:22:30 +000069 void EmitInt8(unsigned Opcode) {
70 Ops.push_back(Opcode & 0xff);
71 OpBegins.push_back(OpBegins.back() + 1);
Logan Chiend8bb4b72013-04-16 12:02:21 +000072 }
73
Logan Chien325823a2013-06-09 12:22:30 +000074 void EmitInt16(unsigned Opcode) {
75 Ops.push_back((Opcode >> 8) & 0xff);
76 Ops.push_back(Opcode & 0xff);
77 OpBegins.push_back(OpBegins.back() + 2);
78 }
Logan Chiend8bb4b72013-04-16 12:02:21 +000079
Logan Chien325823a2013-06-09 12:22:30 +000080 void EmitBytes(const uint8_t *Opcode, size_t Size) {
81 Ops.insert(Ops.end(), Opcode, Opcode + Size);
82 OpBegins.push_back(OpBegins.back() + Size);
83 }
Logan Chiend8bb4b72013-04-16 12:02:21 +000084};
85
86} // namespace llvm
87
88#endif // ARM_UNWIND_OP_ASM_H