PPCMCExpr.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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. bool IsHalf16 = Fixup && Fixup->getTargetKind() == PPC::fixup_ppc_half16;
  100. bool IsHalf16DS =
  101. Fixup && Fixup->getTargetKind() == PPC::fixup_ppc_half16ds;
  102. bool IsHalf16DQ =
  103. Fixup && Fixup->getTargetKind() == PPC::fixup_ppc_half16dq;
  104. bool IsHalf = IsHalf16 || IsHalf16DS || IsHalf16DQ;
  105. if (!IsHalf && Result >= 0x8000)
  106. return false;
  107. if ((IsHalf16DS && (Result & 0x3)) || (IsHalf16DQ && (Result & 0xf)))
  108. return false;
  109. Res = MCValue::get(Result);
  110. } else {
  111. if (!Layout)
  112. return false;
  113. MCContext &Context = Layout->getAssembler().getContext();
  114. const MCSymbolRefExpr *Sym = Value.getSymA();
  115. MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();
  116. if (Modifier != MCSymbolRefExpr::VK_None)
  117. return false;
  118. switch (Kind) {
  119. default:
  120. llvm_unreachable("Invalid kind!");
  121. case VK_PPC_LO:
  122. Modifier = MCSymbolRefExpr::VK_PPC_LO;
  123. break;
  124. case VK_PPC_HI:
  125. Modifier = MCSymbolRefExpr::VK_PPC_HI;
  126. break;
  127. case VK_PPC_HA:
  128. Modifier = MCSymbolRefExpr::VK_PPC_HA;
  129. break;
  130. case VK_PPC_HIGH:
  131. Modifier = MCSymbolRefExpr::VK_PPC_HIGH;
  132. break;
  133. case VK_PPC_HIGHA:
  134. Modifier = MCSymbolRefExpr::VK_PPC_HIGHA;
  135. break;
  136. case VK_PPC_HIGHERA:
  137. Modifier = MCSymbolRefExpr::VK_PPC_HIGHERA;
  138. break;
  139. case VK_PPC_HIGHER:
  140. Modifier = MCSymbolRefExpr::VK_PPC_HIGHER;
  141. break;
  142. case VK_PPC_HIGHEST:
  143. Modifier = MCSymbolRefExpr::VK_PPC_HIGHEST;
  144. break;
  145. case VK_PPC_HIGHESTA:
  146. Modifier = MCSymbolRefExpr::VK_PPC_HIGHESTA;
  147. break;
  148. }
  149. Sym = MCSymbolRefExpr::create(&Sym->getSymbol(), Modifier, Context);
  150. Res = MCValue::get(Sym, Value.getSymB(), Value.getConstant());
  151. }
  152. return true;
  153. }
  154. void PPCMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
  155. Streamer.visitUsedExpr(*getSubExpr());
  156. }