1*9880d681SAndroid Build Coastguard Worker //===-- ARMUnwindOpAsm.h - ARM Unwind Opcodes Assembler ---------*- C++ -*-===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker // 10*9880d681SAndroid Build Coastguard Worker // This file declares the unwind opcode assmebler for ARM exception handling 11*9880d681SAndroid Build Coastguard Worker // table. 12*9880d681SAndroid Build Coastguard Worker // 13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H 16*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h" 19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ARMEHABI.h" 20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/DataTypes.h" 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Worker namespace llvm { 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Worker class MCSymbol; 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Worker class UnwindOpcodeAssembler { 27*9880d681SAndroid Build Coastguard Worker private: 28*9880d681SAndroid Build Coastguard Worker llvm::SmallVector<uint8_t, 32> Ops; 29*9880d681SAndroid Build Coastguard Worker llvm::SmallVector<unsigned, 8> OpBegins; 30*9880d681SAndroid Build Coastguard Worker bool HasPersonality; 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker public: UnwindOpcodeAssembler()33*9880d681SAndroid Build Coastguard Worker UnwindOpcodeAssembler() 34*9880d681SAndroid Build Coastguard Worker : HasPersonality(0) { 35*9880d681SAndroid Build Coastguard Worker OpBegins.push_back(0); 36*9880d681SAndroid Build Coastguard Worker } 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Worker /// Reset the unwind opcode assembler. Reset()39*9880d681SAndroid Build Coastguard Worker void Reset() { 40*9880d681SAndroid Build Coastguard Worker Ops.clear(); 41*9880d681SAndroid Build Coastguard Worker OpBegins.clear(); 42*9880d681SAndroid Build Coastguard Worker OpBegins.push_back(0); 43*9880d681SAndroid Build Coastguard Worker HasPersonality = 0; 44*9880d681SAndroid Build Coastguard Worker } 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Worker /// Set the personality setPersonality(const MCSymbol * Per)47*9880d681SAndroid Build Coastguard Worker void setPersonality(const MCSymbol *Per) { 48*9880d681SAndroid Build Coastguard Worker HasPersonality = 1; 49*9880d681SAndroid Build Coastguard Worker } 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Worker /// Emit unwind opcodes for .save directives 52*9880d681SAndroid Build Coastguard Worker void EmitRegSave(uint32_t RegSave); 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Worker /// Emit unwind opcodes for .vsave directives 55*9880d681SAndroid Build Coastguard Worker void EmitVFPRegSave(uint32_t VFPRegSave); 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker /// Emit unwind opcodes to copy address from source register to $sp. 58*9880d681SAndroid Build Coastguard Worker void EmitSetSP(uint16_t Reg); 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Worker /// Emit unwind opcodes to add $sp with an offset. 61*9880d681SAndroid Build Coastguard Worker void EmitSPOffset(int64_t Offset); 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Worker /// Emit unwind raw opcodes EmitRaw(const SmallVectorImpl<uint8_t> & Opcodes)64*9880d681SAndroid Build Coastguard Worker void EmitRaw(const SmallVectorImpl<uint8_t> &Opcodes) { 65*9880d681SAndroid Build Coastguard Worker Ops.insert(Ops.end(), Opcodes.begin(), Opcodes.end()); 66*9880d681SAndroid Build Coastguard Worker OpBegins.push_back(OpBegins.back() + Opcodes.size()); 67*9880d681SAndroid Build Coastguard Worker } 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Worker /// Finalize the unwind opcode sequence for EmitBytes() 70*9880d681SAndroid Build Coastguard Worker void Finalize(unsigned &PersonalityIndex, 71*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<uint8_t> &Result); 72*9880d681SAndroid Build Coastguard Worker 73*9880d681SAndroid Build Coastguard Worker private: EmitInt8(unsigned Opcode)74*9880d681SAndroid Build Coastguard Worker void EmitInt8(unsigned Opcode) { 75*9880d681SAndroid Build Coastguard Worker Ops.push_back(Opcode & 0xff); 76*9880d681SAndroid Build Coastguard Worker OpBegins.push_back(OpBegins.back() + 1); 77*9880d681SAndroid Build Coastguard Worker } 78*9880d681SAndroid Build Coastguard Worker EmitInt16(unsigned Opcode)79*9880d681SAndroid Build Coastguard Worker void EmitInt16(unsigned Opcode) { 80*9880d681SAndroid Build Coastguard Worker Ops.push_back((Opcode >> 8) & 0xff); 81*9880d681SAndroid Build Coastguard Worker Ops.push_back(Opcode & 0xff); 82*9880d681SAndroid Build Coastguard Worker OpBegins.push_back(OpBegins.back() + 2); 83*9880d681SAndroid Build Coastguard Worker } 84*9880d681SAndroid Build Coastguard Worker EmitBytes(const uint8_t * Opcode,size_t Size)85*9880d681SAndroid Build Coastguard Worker void EmitBytes(const uint8_t *Opcode, size_t Size) { 86*9880d681SAndroid Build Coastguard Worker Ops.insert(Ops.end(), Opcode, Opcode + Size); 87*9880d681SAndroid Build Coastguard Worker OpBegins.push_back(OpBegins.back() + Size); 88*9880d681SAndroid Build Coastguard Worker } 89*9880d681SAndroid Build Coastguard Worker }; 90*9880d681SAndroid Build Coastguard Worker 91*9880d681SAndroid Build Coastguard Worker } // namespace llvm 92*9880d681SAndroid Build Coastguard Worker 93*9880d681SAndroid Build Coastguard Worker #endif 94