//===-- ARMUnwindOpAsm.h - ARM Unwind Opcodes Assembler ---------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file declares the unwind opcode assmebler for ARM exception handling // table. // //===----------------------------------------------------------------------===// #ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H #define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H #include "llvm/ADT/SmallVector.h" #include #include namespace llvm { class MCSymbol; class UnwindOpcodeAssembler { private: SmallVector Ops; SmallVector OpBegins; bool HasPersonality = false; public: UnwindOpcodeAssembler() { OpBegins.push_back(0); } /// Reset the unwind opcode assembler. void Reset() { Ops.clear(); OpBegins.clear(); OpBegins.push_back(0); HasPersonality = false; } /// Set the personality void setPersonality(const MCSymbol *Per) { HasPersonality = true; } /// Emit unwind opcodes for .save directives void EmitRegSave(uint32_t RegSave); /// Emit unwind opcodes for .vsave directives void EmitVFPRegSave(uint32_t VFPRegSave); /// Emit unwind opcodes to copy address from source register to $sp. void EmitSetSP(uint16_t Reg); /// Emit unwind opcodes to add $sp with an offset. void EmitSPOffset(int64_t Offset); /// Emit unwind raw opcodes void EmitRaw(const SmallVectorImpl &Opcodes) { Ops.insert(Ops.end(), Opcodes.begin(), Opcodes.end()); OpBegins.push_back(OpBegins.back() + Opcodes.size()); } /// Finalize the unwind opcode sequence for EmitBytes() void Finalize(unsigned &PersonalityIndex, SmallVectorImpl &Result); private: void EmitInt8(unsigned Opcode) { Ops.push_back(Opcode & 0xff); OpBegins.push_back(OpBegins.back() + 1); } void EmitInt16(unsigned Opcode) { Ops.push_back((Opcode >> 8) & 0xff); Ops.push_back(Opcode & 0xff); OpBegins.push_back(OpBegins.back() + 2); } void EmitBytes(const uint8_t *Opcode, size_t Size) { Ops.insert(Ops.end(), Opcode, Opcode + Size); OpBegins.push_back(OpBegins.back() + Size); } }; } // end namespace llvm #endif // LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H