1 //===-- ARMUnwindOpAsm.h - ARM Unwind Opcodes Assembler ---------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file declares the unwind opcode assmebler for ARM exception handling
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H
16 #define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H
18 #include "llvm/ADT/SmallVector.h"
26 class UnwindOpcodeAssembler {
28 SmallVector<uint8_t, 32> Ops;
29 SmallVector<unsigned, 8> OpBegins;
30 bool HasPersonality = false;
33 UnwindOpcodeAssembler() {
34 OpBegins.push_back(0);
37 /// Reset the unwind opcode assembler.
41 OpBegins.push_back(0);
42 HasPersonality = false;
45 /// Set the personality
46 void setPersonality(const MCSymbol *Per) {
47 HasPersonality = true;
50 /// Emit unwind opcodes for .save directives
51 void EmitRegSave(uint32_t RegSave);
53 /// Emit unwind opcodes for .vsave directives
54 void EmitVFPRegSave(uint32_t VFPRegSave);
56 /// Emit unwind opcodes to copy address from source register to $sp.
57 void EmitSetSP(uint16_t Reg);
59 /// Emit unwind opcodes to add $sp with an offset.
60 void EmitSPOffset(int64_t Offset);
62 /// Emit unwind raw opcodes
63 void EmitRaw(const SmallVectorImpl<uint8_t> &Opcodes) {
64 Ops.insert(Ops.end(), Opcodes.begin(), Opcodes.end());
65 OpBegins.push_back(OpBegins.back() + Opcodes.size());
68 /// Finalize the unwind opcode sequence for EmitBytes()
69 void Finalize(unsigned &PersonalityIndex,
70 SmallVectorImpl<uint8_t> &Result);
73 void EmitInt8(unsigned Opcode) {
74 Ops.push_back(Opcode & 0xff);
75 OpBegins.push_back(OpBegins.back() + 1);
78 void EmitInt16(unsigned Opcode) {
79 Ops.push_back((Opcode >> 8) & 0xff);
80 Ops.push_back(Opcode & 0xff);
81 OpBegins.push_back(OpBegins.back() + 2);
84 void EmitBytes(const uint8_t *Opcode, size_t Size) {
85 Ops.insert(Ops.end(), Opcode, Opcode + Size);
86 OpBegins.push_back(OpBegins.back() + Size);
90 } // end namespace llvm
92 #endif // LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H