1532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien//===-- ARMUnwindOpAsm.h - ARM Unwind Opcodes Assembler ---------*- C++ -*-===// 2532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien// 3532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien// The LLVM Compiler Infrastructure 4532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien// 5532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien// This file is distributed under the University of Illinois Open Source 6532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien// License. See LICENSE.TXT for details. 7532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien// 8532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien//===----------------------------------------------------------------------===// 9532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien// 10532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien// This file declares the unwind opcode assmebler for ARM exception handling 11532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien// table. 12532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien// 13532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien//===----------------------------------------------------------------------===// 14532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 15532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien#ifndef ARM_UNWIND_OP_ASM_H 16532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien#define ARM_UNWIND_OP_ASM_H 17532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 18532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien#include "llvm/ADT/SmallVector.h" 1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/ARMEHABI.h" 20532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien#include "llvm/Support/DataTypes.h" 21532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 22532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chiennamespace llvm { 23532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 24532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chienclass MCSymbol; 25532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 26532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chienclass UnwindOpcodeAssembler { 27532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chienprivate: 2818cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien llvm::SmallVector<uint8_t, 32> Ops; 2918cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien llvm::SmallVector<unsigned, 8> OpBegins; 30532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien bool HasPersonality; 31532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 32532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chienpublic: 33532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien UnwindOpcodeAssembler() 3418cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien : HasPersonality(0) { 3518cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien OpBegins.push_back(0); 36532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien } 37532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 38532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien /// Reset the unwind opcode assembler. 39532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien void Reset() { 4018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien Ops.clear(); 4118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien OpBegins.clear(); 4218cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien OpBegins.push_back(0); 43532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien HasPersonality = 0; 44532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien } 45532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Set the personality 47532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien void setPersonality(const MCSymbol *Per) { 48532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien HasPersonality = 1; 49532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien } 50532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 51532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien /// Emit unwind opcodes for .save directives 52532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien void EmitRegSave(uint32_t RegSave); 53532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 54532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien /// Emit unwind opcodes for .vsave directives 55532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien void EmitVFPRegSave(uint32_t VFPRegSave); 56532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 5718cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien /// Emit unwind opcodes to copy address from source register to $sp. 5818cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien void EmitSetSP(uint16_t Reg); 59532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 6018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien /// Emit unwind opcodes to add $sp with an offset. 61532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien void EmitSPOffset(int64_t Offset); 62532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Emit unwind raw opcodes 6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void EmitRaw(const SmallVectorImpl<uint8_t> &Opcodes) { 6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Ops.insert(Ops.end(), Opcodes.begin(), Opcodes.end()); 6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OpBegins.push_back(OpBegins.back() + Opcodes.size()); 6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 69532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien /// Finalize the unwind opcode sequence for EmitBytes() 7018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien void Finalize(unsigned &PersonalityIndex, 7118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien SmallVectorImpl<uint8_t> &Result); 72532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 73532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chienprivate: 7418cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien void EmitInt8(unsigned Opcode) { 7518cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien Ops.push_back(Opcode & 0xff); 7618cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien OpBegins.push_back(OpBegins.back() + 1); 77532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien } 78532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 7918cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien void EmitInt16(unsigned Opcode) { 8018cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien Ops.push_back((Opcode >> 8) & 0xff); 8118cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien Ops.push_back(Opcode & 0xff); 8218cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien OpBegins.push_back(OpBegins.back() + 2); 8318cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien } 84532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 8518cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien void EmitBytes(const uint8_t *Opcode, size_t Size) { 8618cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien Ops.insert(Ops.end(), Opcode, Opcode + Size); 8718cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien OpBegins.push_back(OpBegins.back() + Size); 8818cba562c8016f8095643b5dd8c4b34b294b62ddLogan Chien } 89532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien}; 90532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 91532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien} // namespace llvm 92532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien 93532854d7ab47d4ec20fd8cec703aa8c89d4eefb2Logan Chien#endif // ARM_UNWIND_OP_ASM_H 94