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 "llvm/Support/ARMEHABI.h" 20#include "llvm/Support/DataTypes.h" 21 22namespace llvm { 23 24class MCSymbol; 25 26class UnwindOpcodeAssembler { 27private: 28 llvm::SmallVector<uint8_t, 32> Ops; 29 llvm::SmallVector<unsigned, 8> OpBegins; 30 bool HasPersonality; 31 32public: 33 UnwindOpcodeAssembler() 34 : HasPersonality(0) { 35 OpBegins.push_back(0); 36 } 37 38 /// Reset the unwind opcode assembler. 39 void Reset() { 40 Ops.clear(); 41 OpBegins.clear(); 42 OpBegins.push_back(0); 43 HasPersonality = 0; 44 } 45 46 /// Set the personality 47 void setPersonality(const MCSymbol *Per) { 48 HasPersonality = 1; 49 } 50 51 /// Emit unwind opcodes for .save directives 52 void EmitRegSave(uint32_t RegSave); 53 54 /// Emit unwind opcodes for .vsave directives 55 void EmitVFPRegSave(uint32_t VFPRegSave); 56 57 /// Emit unwind opcodes to copy address from source register to $sp. 58 void EmitSetSP(uint16_t Reg); 59 60 /// Emit unwind opcodes to add $sp with an offset. 61 void EmitSPOffset(int64_t Offset); 62 63 /// Emit unwind raw opcodes 64 void EmitRaw(const SmallVectorImpl<uint8_t> &Opcodes) { 65 Ops.insert(Ops.end(), Opcodes.begin(), Opcodes.end()); 66 OpBegins.push_back(OpBegins.back() + Opcodes.size()); 67 } 68 69 /// Finalize the unwind opcode sequence for EmitBytes() 70 void Finalize(unsigned &PersonalityIndex, 71 SmallVectorImpl<uint8_t> &Result); 72 73private: 74 void EmitInt8(unsigned Opcode) { 75 Ops.push_back(Opcode & 0xff); 76 OpBegins.push_back(OpBegins.back() + 1); 77 } 78 79 void EmitInt16(unsigned Opcode) { 80 Ops.push_back((Opcode >> 8) & 0xff); 81 Ops.push_back(Opcode & 0xff); 82 OpBegins.push_back(OpBegins.back() + 2); 83 } 84 85 void EmitBytes(const uint8_t *Opcode, size_t Size) { 86 Ops.insert(Ops.end(), Opcode, Opcode + Size); 87 OpBegins.push_back(OpBegins.back() + Size); 88 } 89}; 90 91} // namespace llvm 92 93#endif 94