1//===-- ARMUnwindOpAsm.h - ARM Unwind Opcodes Assembler ---------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file declares the unwind opcode assmebler for ARM exception handling 11// table. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef ARM_UNWIND_OP_ASM_H 16#define ARM_UNWIND_OP_ASM_H 17 18#include "ARMUnwindOp.h" 19 20#include "llvm/ADT/SmallVector.h" 21#include "llvm/ADT/StringRef.h" 22#include "llvm/Support/DataTypes.h" 23 24namespace llvm { 25 26class MCSymbol; 27 28class UnwindOpcodeAssembler { 29private: 30 llvm::SmallVector<uint8_t, 8> Ops; 31 32 unsigned Offset; 33 unsigned PersonalityIndex; 34 bool HasPersonality; 35 36 enum { 37 // The number of bytes to be preserved for the size and personality index 38 // prefix of unwind opcodes. 39 NUM_PRESERVED_PREFIX_BUF = 2 40 }; 41 42public: 43 UnwindOpcodeAssembler() 44 : Ops(NUM_PRESERVED_PREFIX_BUF), Offset(NUM_PRESERVED_PREFIX_BUF), 45 PersonalityIndex(NUM_PERSONALITY_INDEX), HasPersonality(0) { 46 } 47 48 /// Reset the unwind opcode assembler. 49 void Reset() { 50 Ops.resize(NUM_PRESERVED_PREFIX_BUF); 51 Offset = NUM_PRESERVED_PREFIX_BUF; 52 PersonalityIndex = NUM_PERSONALITY_INDEX; 53 HasPersonality = 0; 54 } 55 56 /// Get the size of the payload (including the size byte) 57 size_t size() const { 58 return Ops.size() - Offset; 59 } 60 61 /// Get the beginning of the payload 62 const uint8_t *begin() const { 63 return Ops.begin() + Offset; 64 } 65 66 /// Get the payload 67 StringRef data() const { 68 return StringRef(reinterpret_cast<const char *>(begin()), size()); 69 } 70 71 /// Set the personality index 72 void setPersonality(const MCSymbol *Per) { 73 HasPersonality = 1; 74 } 75 76 /// Get the personality index 77 unsigned getPersonalityIndex() const { 78 return PersonalityIndex; 79 } 80 81 /// Emit unwind opcodes for .save directives 82 void EmitRegSave(uint32_t RegSave); 83 84 /// Emit unwind opcodes for .vsave directives 85 void EmitVFPRegSave(uint32_t VFPRegSave); 86 87 /// Emit unwind opcodes for .setfp directives 88 void EmitSetFP(uint16_t FPReg); 89 90 /// Emit unwind opcodes to update stack pointer 91 void EmitSPOffset(int64_t Offset); 92 93 /// Finalize the unwind opcode sequence for EmitBytes() 94 void Finalize(); 95 96private: 97 /// Get the size of the opcodes in bytes. 98 size_t getOpcodeSize() const { 99 return Ops.size() - NUM_PRESERVED_PREFIX_BUF; 100 } 101 102 /// Add the length prefix to the payload 103 void AddOpcodeSizePrefix(size_t Pos); 104 105 /// Add personality index prefix in some compact format 106 void AddPersonalityIndexPrefix(size_t Pos, unsigned PersonalityIndex); 107 108 /// Fill the words with finish opcode if it is not aligned 109 void EmitFinishOpcodes(); 110}; 111 112} // namespace llvm 113 114#endif // ARM_UNWIND_OP_ASM_H 115