blob: e0c113ecfaa373b3c79819454e22a0cb2b437596 [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
Benjamin Kramera7c40ef2014-08-13 16:26:38 +000015#ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H
16#define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H
Logan Chiend8bb4b72013-04-16 12:02:21 +000017
Logan Chiend8bb4b72013-04-16 12:02:21 +000018#include "llvm/ADT/SmallVector.h"
Saleem Abdulrasoolb961c992014-01-06 00:15:00 +000019#include "llvm/Support/ARMEHABI.h"
Logan Chiend8bb4b72013-04-16 12:02:21 +000020#include "llvm/Support/DataTypes.h"
21
22namespace llvm {
23
24class MCSymbol;
25
26class UnwindOpcodeAssembler {
27private:
Logan Chien325823a2013-06-09 12:22:30 +000028 llvm::SmallVector<uint8_t, 32> Ops;
29 llvm::SmallVector<unsigned, 8> OpBegins;
Logan Chiend8bb4b72013-04-16 12:02:21 +000030 bool HasPersonality;
31
Logan Chiend8bb4b72013-04-16 12:02:21 +000032public:
33 UnwindOpcodeAssembler()
Logan Chien325823a2013-06-09 12:22:30 +000034 : HasPersonality(0) {
35 OpBegins.push_back(0);
Logan Chiend8bb4b72013-04-16 12:02:21 +000036 }
37
38 /// Reset the unwind opcode assembler.
39 void Reset() {
Logan Chien325823a2013-06-09 12:22:30 +000040 Ops.clear();
41 OpBegins.clear();
42 OpBegins.push_back(0);
Logan Chiend8bb4b72013-04-16 12:02:21 +000043 HasPersonality = 0;
44 }
45
Logan Chien2da10212014-01-07 17:47:25 +000046 /// Set the personality
Logan Chiend8bb4b72013-04-16 12:02:21 +000047 void setPersonality(const MCSymbol *Per) {
48 HasPersonality = 1;
49 }
50
Logan Chiend8bb4b72013-04-16 12:02:21 +000051 /// Emit unwind opcodes for .save directives
52 void EmitRegSave(uint32_t RegSave);
53
54 /// Emit unwind opcodes for .vsave directives
55 void EmitVFPRegSave(uint32_t VFPRegSave);
56
Logan Chien325823a2013-06-09 12:22:30 +000057 /// Emit unwind opcodes to copy address from source register to $sp.
58 void EmitSetSP(uint16_t Reg);
Logan Chiend8bb4b72013-04-16 12:02:21 +000059
Logan Chien325823a2013-06-09 12:22:30 +000060 /// Emit unwind opcodes to add $sp with an offset.
Logan Chiend8bb4b72013-04-16 12:02:21 +000061 void EmitSPOffset(int64_t Offset);
62
Saleem Abdulrasoold9f08602014-01-21 02:33:10 +000063 /// Emit unwind raw opcodes
64 void EmitRaw(const SmallVectorImpl<uint8_t> &Opcodes) {
65 Ops.insert(Ops.end(), Opcodes.begin(), Opcodes.end());
66 OpBegins.push_back(OpBegins.back() + Opcodes.size());
67 }
68
Logan Chiend8bb4b72013-04-16 12:02:21 +000069 /// Finalize the unwind opcode sequence for EmitBytes()
Logan Chien325823a2013-06-09 12:22:30 +000070 void Finalize(unsigned &PersonalityIndex,
71 SmallVectorImpl<uint8_t> &Result);
Logan Chiend8bb4b72013-04-16 12:02:21 +000072
73private:
Logan Chien325823a2013-06-09 12:22:30 +000074 void EmitInt8(unsigned Opcode) {
75 Ops.push_back(Opcode & 0xff);
76 OpBegins.push_back(OpBegins.back() + 1);
Logan Chiend8bb4b72013-04-16 12:02:21 +000077 }
78
Logan Chien325823a2013-06-09 12:22:30 +000079 void EmitInt16(unsigned Opcode) {
80 Ops.push_back((Opcode >> 8) & 0xff);
81 Ops.push_back(Opcode & 0xff);
82 OpBegins.push_back(OpBegins.back() + 2);
83 }
Logan Chiend8bb4b72013-04-16 12:02:21 +000084
Logan Chien325823a2013-06-09 12:22:30 +000085 void EmitBytes(const uint8_t *Opcode, size_t Size) {
86 Ops.insert(Ops.end(), Opcode, Opcode + Size);
87 OpBegins.push_back(OpBegins.back() + Size);
88 }
Logan Chiend8bb4b72013-04-16 12:02:21 +000089};
90
91} // namespace llvm
92
Benjamin Kramera7c40ef2014-08-13 16:26:38 +000093#endif