blob: ac67c6efabb7a5d635d97620bce15210ddebc32d [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
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:
Logan Chien325823a2013-06-09 12:22:30 +000030 llvm::SmallVector<uint8_t, 32> Ops;
31 llvm::SmallVector<unsigned, 8> OpBegins;
Logan Chiend8bb4b72013-04-16 12:02:21 +000032 bool HasPersonality;
33
Logan Chiend8bb4b72013-04-16 12:02:21 +000034public:
35 UnwindOpcodeAssembler()
Logan Chien325823a2013-06-09 12:22:30 +000036 : HasPersonality(0) {
37 OpBegins.push_back(0);
Logan Chiend8bb4b72013-04-16 12:02:21 +000038 }
39
40 /// Reset the unwind opcode assembler.
41 void Reset() {
Logan Chien325823a2013-06-09 12:22:30 +000042 Ops.clear();
43 OpBegins.clear();
44 OpBegins.push_back(0);
Logan Chiend8bb4b72013-04-16 12:02:21 +000045 HasPersonality = 0;
46 }
47
Logan Chiend8bb4b72013-04-16 12:02:21 +000048 /// Set the personality index
49 void setPersonality(const MCSymbol *Per) {
50 HasPersonality = 1;
51 }
52
Logan Chiend8bb4b72013-04-16 12:02:21 +000053 /// 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
Logan Chien325823a2013-06-09 12:22:30 +000059 /// Emit unwind opcodes to copy address from source register to $sp.
60 void EmitSetSP(uint16_t Reg);
Logan Chiend8bb4b72013-04-16 12:02:21 +000061
Logan Chien325823a2013-06-09 12:22:30 +000062 /// Emit unwind opcodes to add $sp with an offset.
Logan Chiend8bb4b72013-04-16 12:02:21 +000063 void EmitSPOffset(int64_t Offset);
64
65 /// Finalize the unwind opcode sequence for EmitBytes()
Logan Chien325823a2013-06-09 12:22:30 +000066 void Finalize(unsigned &PersonalityIndex,
67 SmallVectorImpl<uint8_t> &Result);
Logan Chiend8bb4b72013-04-16 12:02:21 +000068
69private:
Logan Chien325823a2013-06-09 12:22:30 +000070 void EmitInt8(unsigned Opcode) {
71 Ops.push_back(Opcode & 0xff);
72 OpBegins.push_back(OpBegins.back() + 1);
Logan Chiend8bb4b72013-04-16 12:02:21 +000073 }
74
Logan Chien325823a2013-06-09 12:22:30 +000075 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 }
Logan Chiend8bb4b72013-04-16 12:02:21 +000080
Logan Chien325823a2013-06-09 12:22:30 +000081 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 }
Logan Chiend8bb4b72013-04-16 12:02:21 +000085};
86
87} // namespace llvm
88
89#endif // ARM_UNWIND_OP_ASM_H