LLVM API Documentation
00001 //===-- ARMUnwindOpAsm.h - ARM Unwind Opcodes Assembler ---------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file declares the unwind opcode assmebler for ARM exception handling 00011 // table. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H 00016 #define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H 00017 00018 #include "llvm/ADT/SmallVector.h" 00019 #include "llvm/Support/ARMEHABI.h" 00020 #include "llvm/Support/DataTypes.h" 00021 00022 namespace llvm { 00023 00024 class MCSymbol; 00025 00026 class UnwindOpcodeAssembler { 00027 private: 00028 llvm::SmallVector<uint8_t, 32> Ops; 00029 llvm::SmallVector<unsigned, 8> OpBegins; 00030 bool HasPersonality; 00031 00032 public: 00033 UnwindOpcodeAssembler() 00034 : HasPersonality(0) { 00035 OpBegins.push_back(0); 00036 } 00037 00038 /// Reset the unwind opcode assembler. 00039 void Reset() { 00040 Ops.clear(); 00041 OpBegins.clear(); 00042 OpBegins.push_back(0); 00043 HasPersonality = 0; 00044 } 00045 00046 /// Set the personality 00047 void setPersonality(const MCSymbol *Per) { 00048 HasPersonality = 1; 00049 } 00050 00051 /// Emit unwind opcodes for .save directives 00052 void EmitRegSave(uint32_t RegSave); 00053 00054 /// Emit unwind opcodes for .vsave directives 00055 void EmitVFPRegSave(uint32_t VFPRegSave); 00056 00057 /// Emit unwind opcodes to copy address from source register to $sp. 00058 void EmitSetSP(uint16_t Reg); 00059 00060 /// Emit unwind opcodes to add $sp with an offset. 00061 void EmitSPOffset(int64_t Offset); 00062 00063 /// Emit unwind raw opcodes 00064 void EmitRaw(const SmallVectorImpl<uint8_t> &Opcodes) { 00065 Ops.insert(Ops.end(), Opcodes.begin(), Opcodes.end()); 00066 OpBegins.push_back(OpBegins.back() + Opcodes.size()); 00067 } 00068 00069 /// Finalize the unwind opcode sequence for EmitBytes() 00070 void Finalize(unsigned &PersonalityIndex, 00071 SmallVectorImpl<uint8_t> &Result); 00072 00073 private: 00074 void EmitInt8(unsigned Opcode) { 00075 Ops.push_back(Opcode & 0xff); 00076 OpBegins.push_back(OpBegins.back() + 1); 00077 } 00078 00079 void EmitInt16(unsigned Opcode) { 00080 Ops.push_back((Opcode >> 8) & 0xff); 00081 Ops.push_back(Opcode & 0xff); 00082 OpBegins.push_back(OpBegins.back() + 2); 00083 } 00084 00085 void EmitBytes(const uint8_t *Opcode, size_t Size) { 00086 Ops.insert(Ops.end(), Opcode, Opcode + Size); 00087 OpBegins.push_back(OpBegins.back() + Size); 00088 } 00089 }; 00090 00091 } // namespace llvm 00092 00093 #endif