//===-- ARMUnwindOpAsm.h - ARM Unwind Opcodes Assembler ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // 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