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/SmallVector.h"
18#include <cstddef>
19#include <cstdint>
20
21namespace llvm {
22
23class MCSymbol;
24
25class UnwindOpcodeAssembler {
26private:
27 SmallVector<uint8_t, 32> Ops;
28 SmallVector<unsigned, 8> OpBegins;
29 bool HasPersonality = false;
30
31public:
32 UnwindOpcodeAssembler() {
33 OpBegins.push_back(Elt: 0);
34 }
35
36 /// Reset the unwind opcode assembler.
37 void Reset() {
38 Ops.clear();
39 OpBegins.clear();
40 OpBegins.push_back(Elt: 0);
41 HasPersonality = false;
42 }
43
44 /// Set the personality
45 void setPersonality(const MCSymbol *Per) {
46 HasPersonality = true;
47 }
48
49 /// Emit unwind opcodes for .save directives
50 void EmitRegSave(uint32_t RegSave);
51
52 /// Emit unwind opcodes for .vsave directives
53 void EmitVFPRegSave(uint32_t VFPRegSave);
54
55 /// Emit unwind opcodes to copy address from source register to $sp.
56 void EmitSetSP(uint16_t Reg);
57
58 /// Emit unwind opcodes to add $sp with an offset.
59 void EmitSPOffset(int64_t Offset);
60
61 /// Emit unwind raw opcodes
62 void EmitRaw(const SmallVectorImpl<uint8_t> &Opcodes) {
63 Ops.insert(I: Ops.end(), From: Opcodes.begin(), To: Opcodes.end());
64 OpBegins.push_back(Elt: OpBegins.back() + Opcodes.size());
65 }
66
67 /// Finalize the unwind opcode sequence for emitBytes()
68 void Finalize(unsigned &PersonalityIndex,
69 SmallVectorImpl<uint8_t> &Result);
70
71private:
72 void EmitInt8(unsigned Opcode) {
73 Ops.push_back(Elt: Opcode & 0xff);
74 OpBegins.push_back(Elt: OpBegins.back() + 1);
75 }
76
77 void EmitInt16(unsigned Opcode) {
78 Ops.push_back(Elt: (Opcode >> 8) & 0xff);
79 Ops.push_back(Elt: Opcode & 0xff);
80 OpBegins.push_back(Elt: OpBegins.back() + 2);
81 }
82
83 void emitBytes(const uint8_t *Opcode, size_t Size) {
84 Ops.insert(I: Ops.end(), From: Opcode, To: Opcode + Size);
85 OpBegins.push_back(Elt: OpBegins.back() + Size);
86 }
87};
88
89} // end namespace llvm
90
91#endif // LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H
92