PPCXCOFFStreamer.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. //===-------- PPCXCOFFStreamer.cpp - XCOFF Object Output ------------------===//
  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 is a custom MCXCOFFStreamer for PowerPC.
  10. //
  11. // The purpose of the custom XCOFF streamer is to allow us to intercept
  12. // instructions as they are being emitted and align all 8 byte instructions
  13. // to a 64 byte boundary if required (by adding a 4 byte nop). This is important
  14. // because 8 byte instructions are not allowed to cross 64 byte boundaries
  15. // and by aligning anything that is within 4 bytes of the boundary we can
  16. // guarantee that the 8 byte instructions do not cross that boundary.
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #include "PPCXCOFFStreamer.h"
  20. #include "PPCMCCodeEmitter.h"
  21. #include "llvm/BinaryFormat/XCOFF.h"
  22. #include "llvm/MC/MCAsmBackend.h"
  23. #include "llvm/MC/MCAssembler.h"
  24. #include "llvm/MC/MCCodeEmitter.h"
  25. #include "llvm/MC/MCDirectives.h"
  26. #include "llvm/MC/MCObjectWriter.h"
  27. #include "llvm/MC/MCSectionXCOFF.h"
  28. #include "llvm/MC/MCSymbolXCOFF.h"
  29. #include "llvm/MC/TargetRegistry.h"
  30. using namespace llvm;
  31. PPCXCOFFStreamer::PPCXCOFFStreamer(MCContext &Context,
  32. std::unique_ptr<MCAsmBackend> MAB,
  33. std::unique_ptr<MCObjectWriter> OW,
  34. std::unique_ptr<MCCodeEmitter> Emitter)
  35. : MCXCOFFStreamer(Context, std::move(MAB), std::move(OW),
  36. std::move(Emitter)) {}
  37. void PPCXCOFFStreamer::emitPrefixedInstruction(const MCInst &Inst,
  38. const MCSubtargetInfo &STI) {
  39. // Prefixed instructions must not cross a 64-byte boundary (i.e. prefix is
  40. // before the boundary and the remaining 4-bytes are after the boundary). In
  41. // order to achieve this, a nop is added prior to any such boundary-crossing
  42. // prefixed instruction. Align to 64 bytes if possible but add a maximum of 4
  43. // bytes when trying to do that. If alignment requires adding more than 4
  44. // bytes then the instruction won't be aligned.
  45. emitCodeAlignment(Align(64), &STI, 4);
  46. // Emit the instruction.
  47. // Since the previous emit created a new fragment then adding this instruction
  48. // also forces the addition of a new fragment. Inst is now the first
  49. // instruction in that new fragment.
  50. MCXCOFFStreamer::emitInstruction(Inst, STI);
  51. }
  52. void PPCXCOFFStreamer::emitInstruction(const MCInst &Inst,
  53. const MCSubtargetInfo &STI) {
  54. PPCMCCodeEmitter *Emitter =
  55. static_cast<PPCMCCodeEmitter *>(getAssembler().getEmitterPtr());
  56. // Special handling is only for prefixed instructions.
  57. if (!Emitter->isPrefixedInstruction(Inst)) {
  58. MCXCOFFStreamer::emitInstruction(Inst, STI);
  59. return;
  60. }
  61. emitPrefixedInstruction(Inst, STI);
  62. }
  63. MCXCOFFStreamer *
  64. llvm::createPPCXCOFFStreamer(MCContext &Context,
  65. std::unique_ptr<MCAsmBackend> MAB,
  66. std::unique_ptr<MCObjectWriter> OW,
  67. std::unique_ptr<MCCodeEmitter> Emitter) {
  68. return new PPCXCOFFStreamer(Context, std::move(MAB), std::move(OW),
  69. std::move(Emitter));
  70. }