PPCMCExpr.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. //===-- PPCMCExpr.cpp - PPC specific MC expression classes ----------------===//
  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. #include "PPCMCExpr.h"
  9. #include "PPCFixupKinds.h"
  10. #include "llvm/MC/MCAsmInfo.h"
  11. #include "llvm/MC/MCAssembler.h"
  12. #include "llvm/MC/MCContext.h"
  13. #include "llvm/MC/MCObjectStreamer.h"
  14. using namespace llvm;
  15. #define DEBUG_TYPE "ppcmcexpr"
  16. const PPCMCExpr *PPCMCExpr::create(VariantKind Kind, const MCExpr *Expr,
  17. MCContext &Ctx) {
  18. return new (Ctx) PPCMCExpr(Kind, Expr);
  19. }
  20. void PPCMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
  21. getSubExpr()->print(OS, MAI);
  22. switch (Kind) {
  23. default:
  24. llvm_unreachable("Invalid kind!");
  25. case VK_PPC_LO:
  26. OS << "@l";
  27. break;
  28. case VK_PPC_HI:
  29. OS << "@h";
  30. break;
  31. case VK_PPC_HA:
  32. OS << "@ha";
  33. break;
  34. case VK_PPC_HIGH:
  35. OS << "@high";
  36. break;
  37. case VK_PPC_HIGHA:
  38. OS << "@higha";
  39. break;
  40. case VK_PPC_HIGHER:
  41. OS << "@higher";
  42. break;
  43. case VK_PPC_HIGHERA:
  44. OS << "@highera";
  45. break;
  46. case VK_PPC_HIGHEST:
  47. OS << "@highest";
  48. break;
  49. case VK_PPC_HIGHESTA:
  50. OS << "@highesta";
  51. break;
  52. }
  53. }
  54. bool
  55. PPCMCExpr::evaluateAsConstant(int64_t &Res) const {
  56. MCValue Value;
  57. if (!getSubExpr()->evaluateAsRelocatable(Value, nullptr, nullptr))
  58. return false;
  59. if (!Value.isAbsolute())
  60. return false;
  61. Res = evaluateAsInt64(Value.getConstant());
  62. return true;
  63. }
  64. int64_t
  65. PPCMCExpr::evaluateAsInt64(int64_t Value) const {
  66. switch (Kind) {
  67. case VK_PPC_LO:
  68. return Value & 0xffff;
  69. case VK_PPC_HI:
  70. return (Value >> 16) & 0xffff;
  71. case VK_PPC_HA:
  72. return ((Value + 0x8000) >> 16) & 0xffff;
  73. case VK_PPC_HIGH:
  74. return (Value >> 16) & 0xffff;
  75. case VK_PPC_HIGHA:
  76. return ((Value + 0x8000) >> 16) & 0xffff;
  77. case VK_PPC_HIGHER:
  78. return (Value >> 32) & 0xffff;
  79. case VK_PPC_HIGHERA:
  80. return ((Value + 0x8000) >> 32) & 0xffff;
  81. case VK_PPC_HIGHEST:
  82. return (Value >> 48) & 0xffff;
  83. case VK_PPC_HIGHESTA:
  84. return ((Value + 0x8000) >> 48) & 0xffff;
  85. case VK_PPC_None:
  86. break;
  87. }
  88. llvm_unreachable("Invalid kind!");
  89. }
  90. bool
  91. PPCMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
  92. const MCAsmLayout *Layout,
  93. const MCFixup *Fixup) const {
  94. MCValue Value;
  95. if (!getSubExpr()->evaluateAsRelocatable(Value, Layout, Fixup))
  96. return false;
  97. if (Value.isAbsolute()) {
  98. int64_t Result = evaluateAsInt64(Value.getConstant());
  99. if ((Fixup == nullptr || (unsigned)Fixup->getKind() != PPC::fixup_ppc_half16) &&
  100. (Result >= 0x8000))
  101. return false;
  102. Res = MCValue::get(Result);
  103. } else {
  104. if (!Layout)
  105. return false;
  106. MCContext &Context = Layout->getAssembler().getContext();
  107. const MCSymbolRefExpr *Sym = Value.getSymA();
  108. MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();
  109. if (Modifier != MCSymbolRefExpr::VK_None)
  110. return false;
  111. switch (Kind) {
  112. default:
  113. llvm_unreachable("Invalid kind!");
  114. case VK_PPC_LO:
  115. Modifier = MCSymbolRefExpr::VK_PPC_LO;
  116. break;
  117. case VK_PPC_HI:
  118. Modifier = MCSymbolRefExpr::VK_PPC_HI;
  119. break;
  120. case VK_PPC_HA:
  121. Modifier = MCSymbolRefExpr::VK_PPC_HA;
  122. break;
  123. case VK_PPC_HIGH:
  124. Modifier = MCSymbolRefExpr::VK_PPC_HIGH;
  125. break;
  126. case VK_PPC_HIGHA:
  127. Modifier = MCSymbolRefExpr::VK_PPC_HIGHA;
  128. break;
  129. case VK_PPC_HIGHERA:
  130. Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA;
  131. break;
  132. case VK_PPC_HIGHER:
  133. Modifier = MCSymbolRefExpr::VK_PPC_HIGHER;
  134. break;
  135. case VK_PPC_HIGHEST:
  136. Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST;
  137. break;
  138. case VK_PPC_HIGHESTA:
  139. Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA;
  140. break;
  141. }
  142. Sym = MCSymbolRefExpr::create(&Sym->getSymbol(), Modifier, Context);
  143. Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant());
  144. }
  145. return true;
  146. }
  147. void PPCMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
  148. Streamer.visitUsedExpr(*getSubExpr());
  149. }