1251607Sdim//===-- ARMUnwindOpAsm.h - ARM Unwind Opcodes Assembler ---------*- C++ -*-===// 2251607Sdim// 3251607Sdim// The LLVM Compiler Infrastructure 4251607Sdim// 5251607Sdim// This file is distributed under the University of Illinois Open Source 6251607Sdim// License. See LICENSE.TXT for details. 7251607Sdim// 8251607Sdim//===----------------------------------------------------------------------===// 9251607Sdim// 10251607Sdim// This file declares the unwind opcode assmebler for ARM exception handling 11251607Sdim// table. 12251607Sdim// 13251607Sdim//===----------------------------------------------------------------------===// 14251607Sdim 15251607Sdim#ifndef ARM_UNWIND_OP_ASM_H 16251607Sdim#define ARM_UNWIND_OP_ASM_H 17251607Sdim 18251607Sdim#include "ARMUnwindOp.h" 19251607Sdim 20251607Sdim#include "llvm/ADT/SmallVector.h" 21251607Sdim#include "llvm/ADT/StringRef.h" 22251607Sdim#include "llvm/Support/DataTypes.h" 23251607Sdim 24251607Sdimnamespace llvm { 25251607Sdim 26251607Sdimclass MCSymbol; 27251607Sdim 28251607Sdimclass UnwindOpcodeAssembler { 29251607Sdimprivate: 30263508Sdim llvm::SmallVector<uint8_t, 32> Ops; 31263508Sdim llvm::SmallVector<unsigned, 8> OpBegins; 32251607Sdim bool HasPersonality; 33251607Sdim 34251607Sdimpublic: 35251607Sdim UnwindOpcodeAssembler() 36263508Sdim : HasPersonality(0) { 37263508Sdim OpBegins.push_back(0); 38251607Sdim } 39251607Sdim 40251607Sdim /// Reset the unwind opcode assembler. 41251607Sdim void Reset() { 42263508Sdim Ops.clear(); 43263508Sdim OpBegins.clear(); 44263508Sdim OpBegins.push_back(0); 45251607Sdim HasPersonality = 0; 46251607Sdim } 47251607Sdim 48251607Sdim /// Set the personality index 49251607Sdim void setPersonality(const MCSymbol *Per) { 50251607Sdim HasPersonality = 1; 51251607Sdim } 52251607Sdim 53251607Sdim /// Emit unwind opcodes for .save directives 54251607Sdim void EmitRegSave(uint32_t RegSave); 55251607Sdim 56251607Sdim /// Emit unwind opcodes for .vsave directives 57251607Sdim void EmitVFPRegSave(uint32_t VFPRegSave); 58251607Sdim 59263508Sdim /// Emit unwind opcodes to copy address from source register to $sp. 60263508Sdim void EmitSetSP(uint16_t Reg); 61251607Sdim 62263508Sdim /// Emit unwind opcodes to add $sp with an offset. 63251607Sdim void EmitSPOffset(int64_t Offset); 64251607Sdim 65251607Sdim /// Finalize the unwind opcode sequence for EmitBytes() 66263508Sdim void Finalize(unsigned &PersonalityIndex, 67263508Sdim SmallVectorImpl<uint8_t> &Result); 68251607Sdim 69251607Sdimprivate: 70263508Sdim void EmitInt8(unsigned Opcode) { 71263508Sdim Ops.push_back(Opcode & 0xff); 72263508Sdim OpBegins.push_back(OpBegins.back() + 1); 73251607Sdim } 74251607Sdim 75263508Sdim void EmitInt16(unsigned Opcode) { 76263508Sdim Ops.push_back((Opcode >> 8) & 0xff); 77263508Sdim Ops.push_back(Opcode & 0xff); 78263508Sdim OpBegins.push_back(OpBegins.back() + 2); 79263508Sdim } 80251607Sdim 81263508Sdim void EmitBytes(const uint8_t *Opcode, size_t Size) { 82263508Sdim Ops.insert(Ops.end(), Opcode, Opcode + Size); 83263508Sdim OpBegins.push_back(OpBegins.back() + Size); 84263508Sdim } 85251607Sdim}; 86251607Sdim 87251607Sdim} // namespace llvm 88251607Sdim 89251607Sdim#endif // ARM_UNWIND_OP_ASM_H 90