93 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file declares the unwind opcode assembler for ARM exception handling10// table.11//12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H15#define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H16 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(0);35 }36 37 /// Reset the unwind opcode assembler.38 void Reset() {39 Ops.clear();40 OpBegins.clear();41 OpBegins.push_back(0);42 HasPersonality = false;43 }44 45 /// Set the personality46 void setPersonality(const MCSymbol *Per) {47 HasPersonality = true;48 }49 50 /// Emit unwind opcodes for .save directives51 void EmitRegSave(uint32_t RegSave);52 53 /// Emit unwind opcodes for .vsave directives54 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 opcodes63 void EmitRaw(const SmallVectorImpl<uint8_t> &Opcodes) {64 llvm::append_range(Ops, Opcodes);65 OpBegins.push_back(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(Opcode & 0xff);75 OpBegins.push_back(OpBegins.back() + 1);76 }77 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);82 }83 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);87 }88};89 90} // end namespace llvm91 92#endif // LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H93