LLVM API Documentation

ARMUnwindOpAsm.h
Go to the documentation of this file.
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