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