1//===-- ARMUnwindOpAsm.h - ARM Unwind Opcodes Assembler ---------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file declares the unwind opcode assembler for ARM exception handling
10// table.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H
15#define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H
16
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/SmallVector.h"
19#include <cstddef>
20#include <cstdint>
21
22namespace llvm {
23
24class MCSymbol;
25
26class UnwindOpcodeAssembler {
27private:
28 SmallVector<uint8_t, 32> Ops;
29 SmallVector<unsigned, 8> OpBegins;
30 bool HasPersonality = false;
31
32public:
33 UnwindOpcodeAssembler() {
34 OpBegins.push_back(Elt: 0);
35 }
36
37 /// Reset the unwind opcode assembler.
38 void Reset() {
39 Ops.clear();
40 OpBegins.clear();
41 OpBegins.push_back(Elt: 0);
42 HasPersonality = false;
43 }
44
45 /// Set the personality
46 void setPersonality(const MCSymbol *Per) {
47 HasPersonality = true;
48 }
49
50 /// Emit unwind opcodes for .save directives
51 void EmitRegSave(uint32_t RegSave);
52
53 /// Emit unwind opcodes for .vsave directives
54 void EmitVFPRegSave(uint32_t VFPRegSave);
55
56 /// Emit unwind opcodes to copy address from source register to $sp.
57 void EmitSetSP(uint16_t Reg);
58
59 /// Emit unwind opcodes to add $sp with an offset.
60 void EmitSPOffset(int64_t Offset);
61
62 /// Emit unwind raw opcodes
63 void EmitRaw(const SmallVectorImpl<uint8_t> &Opcodes) {
64 llvm::append_range(C&: Ops, R: Opcodes);
65 OpBegins.push_back(Elt: OpBegins.back() + Opcodes.size());
66 }
67
68 /// Finalize the unwind opcode sequence for emitBytes()
69 void Finalize(unsigned &PersonalityIndex,
70 SmallVectorImpl<uint8_t> &Result);
71
72private:
73 void EmitInt8(unsigned Opcode) {
74 Ops.push_back(Elt: Opcode & 0xff);
75 OpBegins.push_back(Elt: OpBegins.back() + 1);
76 }
77
78 void EmitInt16(unsigned Opcode) {
79 Ops.push_back(Elt: (Opcode >> 8) & 0xff);
80 Ops.push_back(Elt: Opcode & 0xff);
81 OpBegins.push_back(Elt: OpBegins.back() + 2);
82 }
83
84 void emitBytes(const uint8_t *Opcode, size_t Size) {
85 Ops.insert(I: Ops.end(), From: Opcode, To: Opcode + Size);
86 OpBegins.push_back(Elt: OpBegins.back() + Size);
87 }
88};
89
90} // end namespace llvm
91
92#endif // LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H
93