ARMUnwindOpAsm.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. //===-- ARMUnwindOpAsm.h - ARM Unwind Opcodes Assembler ---------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file declares the unwind opcode assembler for ARM exception handling
  10. // table.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H
  14. #define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H
  15. #include "llvm/ADT/SmallVector.h"
  16. #include <cstddef>
  17. #include <cstdint>
  18. namespace llvm {
  19. class MCSymbol;
  20. class UnwindOpcodeAssembler {
  21. private:
  22. SmallVector<uint8_t, 32> Ops;
  23. SmallVector<unsigned, 8> OpBegins;
  24. bool HasPersonality = false;
  25. public:
  26. UnwindOpcodeAssembler() {
  27. OpBegins.push_back(0);
  28. }
  29. /// Reset the unwind opcode assembler.
  30. void Reset() {
  31. Ops.clear();
  32. OpBegins.clear();
  33. OpBegins.push_back(0);
  34. HasPersonality = false;
  35. }
  36. /// Set the personality
  37. void setPersonality(const MCSymbol *Per) {
  38. HasPersonality = true;
  39. }
  40. /// Emit unwind opcodes for .save directives
  41. void EmitRegSave(uint32_t RegSave);
  42. /// Emit unwind opcodes for .vsave directives
  43. void EmitVFPRegSave(uint32_t VFPRegSave);
  44. /// Emit unwind opcodes to copy address from source register to $sp.
  45. void EmitSetSP(uint16_t Reg);
  46. /// Emit unwind opcodes to add $sp with an offset.
  47. void EmitSPOffset(int64_t Offset);
  48. /// Emit unwind raw opcodes
  49. void EmitRaw(const SmallVectorImpl<uint8_t> &Opcodes) {
  50. Ops.insert(Ops.end(), Opcodes.begin(), Opcodes.end());
  51. OpBegins.push_back(OpBegins.back() + Opcodes.size());
  52. }
  53. /// Finalize the unwind opcode sequence for emitBytes()
  54. void Finalize(unsigned &PersonalityIndex,
  55. SmallVectorImpl<uint8_t> &Result);
  56. private:
  57. void EmitInt8(unsigned Opcode) {
  58. Ops.push_back(Opcode & 0xff);
  59. OpBegins.push_back(OpBegins.back() + 1);
  60. }
  61. void EmitInt16(unsigned Opcode) {
  62. Ops.push_back((Opcode >> 8) & 0xff);
  63. Ops.push_back(Opcode & 0xff);
  64. OpBegins.push_back(OpBegins.back() + 2);
  65. }
  66. void emitBytes(const uint8_t *Opcode, size_t Size) {
  67. Ops.insert(Ops.end(), Opcode, Opcode + Size);
  68. OpBegins.push_back(OpBegins.back() + Size);
  69. }
  70. };
  71. } // end namespace llvm
  72. #endif // LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMUNWINDOPASM_H