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 LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H 16 #define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H 17 18 #include "llvm/ADT/SmallVector.h" 19 #include <cstddef> 20 #include <cstdint> 21 22 namespace llvm { 23 24 class MCSymbol; 25 26 class UnwindOpcodeAssembler { 27 private: 28 SmallVector<uint8_t, 32> Ops; 29 SmallVector<unsigned, 8> OpBegins; 30 bool HasPersonality = false; 31 32 public: UnwindOpcodeAssembler()33 UnwindOpcodeAssembler() { 34 OpBegins.push_back(0); 35 } 36 37 /// Reset the unwind opcode assembler. Reset()38 void Reset() { 39 Ops.clear(); 40 OpBegins.clear(); 41 OpBegins.push_back(0); 42 HasPersonality = false; 43 } 44 45 /// Set the personality setPersonality(const MCSymbol * Per)46 void setPersonality(const MCSymbol *Per) { 47 HasPersonality = true; 48 } 49 50 /// Emit unwind opcodes for .save directives 51 void EmitRegSave(uint32_t RegSave); 52 53 /// Emit unwind opcodes for .vsave directives 54 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 opcodes EmitRaw(const SmallVectorImpl<uint8_t> & Opcodes)63 void EmitRaw(const SmallVectorImpl<uint8_t> &Opcodes) { 64 Ops.insert(Ops.end(), Opcodes.begin(), Opcodes.end()); 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 72 private: EmitInt8(unsigned Opcode)73 void EmitInt8(unsigned Opcode) { 74 Ops.push_back(Opcode & 0xff); 75 OpBegins.push_back(OpBegins.back() + 1); 76 } 77 EmitInt16(unsigned Opcode)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 EmitBytes(const uint8_t * Opcode,size_t Size)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 llvm 91 92 #endif // LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H 93