LoongArchELFStreamer.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. //===-- LoongArchELFStreamer.cpp - LoongArch ELF Target Streamer Methods --===//
  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 provides LoongArch specific target streamer methods.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "LoongArchELFStreamer.h"
  13. #include "LoongArchAsmBackend.h"
  14. #include "llvm/BinaryFormat/ELF.h"
  15. #include "llvm/MC/MCAssembler.h"
  16. #include "llvm/MC/MCCodeEmitter.h"
  17. #include "llvm/MC/MCObjectWriter.h"
  18. using namespace llvm;
  19. // This part is for ELF object output.
  20. LoongArchTargetELFStreamer::LoongArchTargetELFStreamer(
  21. MCStreamer &S, const MCSubtargetInfo &STI)
  22. : LoongArchTargetStreamer(S) {
  23. // FIXME: select appropriate ABI.
  24. setTargetABI(STI.getTargetTriple().isArch64Bit() ? LoongArchABI::ABI_LP64D
  25. : LoongArchABI::ABI_ILP32D);
  26. }
  27. MCELFStreamer &LoongArchTargetELFStreamer::getStreamer() {
  28. return static_cast<MCELFStreamer &>(Streamer);
  29. }
  30. void LoongArchTargetELFStreamer::finish() {
  31. LoongArchTargetStreamer::finish();
  32. MCAssembler &MCA = getStreamer().getAssembler();
  33. LoongArchABI::ABI ABI = getTargetABI();
  34. // Figure out the e_flags.
  35. //
  36. // Bitness is already represented with the EI_CLASS byte in the current spec,
  37. // so here we only record the base ABI modifier. Also set the object file ABI
  38. // version to v1, as upstream LLVM cannot handle the previous stack-machine-
  39. // based relocs from day one.
  40. //
  41. // Refer to LoongArch ELF psABI v2.01 for details.
  42. unsigned EFlags = MCA.getELFHeaderEFlags();
  43. EFlags |= ELF::EF_LOONGARCH_OBJABI_V1;
  44. switch (ABI) {
  45. case LoongArchABI::ABI_ILP32S:
  46. case LoongArchABI::ABI_LP64S:
  47. EFlags |= ELF::EF_LOONGARCH_ABI_SOFT_FLOAT;
  48. break;
  49. case LoongArchABI::ABI_ILP32F:
  50. case LoongArchABI::ABI_LP64F:
  51. EFlags |= ELF::EF_LOONGARCH_ABI_SINGLE_FLOAT;
  52. break;
  53. case LoongArchABI::ABI_ILP32D:
  54. case LoongArchABI::ABI_LP64D:
  55. EFlags |= ELF::EF_LOONGARCH_ABI_DOUBLE_FLOAT;
  56. break;
  57. case LoongArchABI::ABI_Unknown:
  58. llvm_unreachable("Improperly initialized target ABI");
  59. }
  60. MCA.setELFHeaderEFlags(EFlags);
  61. }
  62. namespace {
  63. class LoongArchELFStreamer : public MCELFStreamer {
  64. public:
  65. LoongArchELFStreamer(MCContext &C, std::unique_ptr<MCAsmBackend> MAB,
  66. std::unique_ptr<MCObjectWriter> MOW,
  67. std::unique_ptr<MCCodeEmitter> MCE)
  68. : MCELFStreamer(C, std::move(MAB), std::move(MOW), std::move(MCE)) {}
  69. };
  70. } // end namespace
  71. namespace llvm {
  72. MCELFStreamer *createLoongArchELFStreamer(MCContext &C,
  73. std::unique_ptr<MCAsmBackend> MAB,
  74. std::unique_ptr<MCObjectWriter> MOW,
  75. std::unique_ptr<MCCodeEmitter> MCE,
  76. bool RelaxAll) {
  77. LoongArchELFStreamer *S = new LoongArchELFStreamer(
  78. C, std::move(MAB), std::move(MOW), std::move(MCE));
  79. S->getAssembler().setRelaxAll(RelaxAll);
  80. return S;
  81. }
  82. } // end namespace llvm