Colin LeMahieu | 7cd0892 | 2015-11-09 04:07:48 +0000 | [diff] [blame] | 1 | //===-- HexagonMCExpr.cpp - Hexagon specific MC expression classes |
| 2 | //----------===// |
| 3 | // |
Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 4 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 5 | // See https://llvm.org/LICENSE.txt for license information. |
| 6 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
Colin LeMahieu | 7cd0892 | 2015-11-09 04:07:48 +0000 | [diff] [blame] | 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | |
| 10 | #include "HexagonMCExpr.h" |
Benjamin Kramer | 27c769d | 2018-09-10 12:53:46 +0000 | [diff] [blame] | 11 | #include "llvm/BinaryFormat/ELF.h" |
Colin LeMahieu | 7cd0892 | 2015-11-09 04:07:48 +0000 | [diff] [blame] | 12 | #include "llvm/MC/MCContext.h" |
Colin LeMahieu | 98c8e07 | 2016-02-15 18:42:07 +0000 | [diff] [blame] | 13 | #include "llvm/MC/MCStreamer.h" |
Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 14 | #include "llvm/MC/MCSymbolELF.h" |
Colin LeMahieu | 7cd0892 | 2015-11-09 04:07:48 +0000 | [diff] [blame] | 15 | #include "llvm/MC/MCValue.h" |
| 16 | #include "llvm/Support/raw_ostream.h" |
| 17 | |
| 18 | using namespace llvm; |
| 19 | |
| 20 | #define DEBUG_TYPE "hexagon-mcexpr" |
| 21 | |
Colin LeMahieu | c7b2124 | 2016-02-15 18:47:55 +0000 | [diff] [blame] | 22 | HexagonMCExpr *HexagonMCExpr::create(MCExpr const *Expr, MCContext &Ctx) { |
Colin LeMahieu | 98c8e07 | 2016-02-15 18:42:07 +0000 | [diff] [blame] | 23 | return new (Ctx) HexagonMCExpr(Expr); |
Colin LeMahieu | 7cd0892 | 2015-11-09 04:07:48 +0000 | [diff] [blame] | 24 | } |
| 25 | |
Colin LeMahieu | 98c8e07 | 2016-02-15 18:42:07 +0000 | [diff] [blame] | 26 | bool HexagonMCExpr::evaluateAsRelocatableImpl(MCValue &Res, |
| 27 | MCAsmLayout const *Layout, |
| 28 | MCFixup const *Fixup) const { |
Colin LeMahieu | 7cd0892 | 2015-11-09 04:07:48 +0000 | [diff] [blame] | 29 | return Expr->evaluateAsRelocatable(Res, Layout, Fixup); |
| 30 | } |
| 31 | |
Colin LeMahieu | 98c8e07 | 2016-02-15 18:42:07 +0000 | [diff] [blame] | 32 | void HexagonMCExpr::visitUsedExpr(MCStreamer &Streamer) const { |
| 33 | Streamer.visitUsedExpr(*Expr); |
| 34 | } |
Colin LeMahieu | 7cd0892 | 2015-11-09 04:07:48 +0000 | [diff] [blame] | 35 | |
Colin LeMahieu | 98c8e07 | 2016-02-15 18:42:07 +0000 | [diff] [blame] | 36 | MCFragment *llvm::HexagonMCExpr::findAssociatedFragment() const { |
Colin LeMahieu | 7cd0892 | 2015-11-09 04:07:48 +0000 | [diff] [blame] | 37 | return Expr->findAssociatedFragment(); |
| 38 | } |
| 39 | |
Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 40 | static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { |
| 41 | switch (Expr->getKind()) { |
| 42 | case MCExpr::Target: |
| 43 | llvm_unreachable("Cannot handle nested target MCExpr"); |
| 44 | break; |
| 45 | case MCExpr::Constant: |
| 46 | break; |
| 47 | |
| 48 | case MCExpr::Binary: { |
| 49 | const MCBinaryExpr *be = cast<MCBinaryExpr>(Expr); |
| 50 | fixELFSymbolsInTLSFixupsImpl(be->getLHS(), Asm); |
| 51 | fixELFSymbolsInTLSFixupsImpl(be->getRHS(), Asm); |
| 52 | break; |
| 53 | } |
| 54 | case MCExpr::SymbolRef: { |
| 55 | const MCSymbolRefExpr &symRef = *cast<MCSymbolRefExpr>(Expr); |
| 56 | switch (symRef.getKind()) { |
| 57 | default: |
| 58 | return; |
| 59 | case MCSymbolRefExpr::VK_Hexagon_GD_GOT: |
| 60 | case MCSymbolRefExpr::VK_Hexagon_LD_GOT: |
| 61 | case MCSymbolRefExpr::VK_Hexagon_GD_PLT: |
| 62 | case MCSymbolRefExpr::VK_Hexagon_LD_PLT: |
| 63 | case MCSymbolRefExpr::VK_Hexagon_IE: |
| 64 | case MCSymbolRefExpr::VK_Hexagon_IE_GOT: |
| 65 | case MCSymbolRefExpr::VK_TPREL: |
| 66 | break; |
| 67 | } |
| 68 | cast<MCSymbolELF>(symRef.getSymbol()).setType(ELF::STT_TLS); |
| 69 | break; |
| 70 | } |
| 71 | case MCExpr::Unary: |
| 72 | fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm); |
| 73 | break; |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | void HexagonMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const { |
| 78 | auto expr = getExpr(); |
| 79 | fixELFSymbolsInTLSFixupsImpl(expr, Asm); |
| 80 | } |
Colin LeMahieu | 7cd0892 | 2015-11-09 04:07:48 +0000 | [diff] [blame] | 81 | |
Colin LeMahieu | 98c8e07 | 2016-02-15 18:42:07 +0000 | [diff] [blame] | 82 | MCExpr const *HexagonMCExpr::getExpr() const { return Expr; } |
Colin LeMahieu | 7cd0892 | 2015-11-09 04:07:48 +0000 | [diff] [blame] | 83 | |
Colin LeMahieu | 98c8e07 | 2016-02-15 18:42:07 +0000 | [diff] [blame] | 84 | void HexagonMCExpr::setMustExtend(bool Val) { |
| 85 | assert((!Val || !MustNotExtend) && "Extension contradiction"); |
| 86 | MustExtend = Val; |
| 87 | } |
| 88 | |
| 89 | bool HexagonMCExpr::mustExtend() const { return MustExtend; } |
| 90 | void HexagonMCExpr::setMustNotExtend(bool Val) { |
| 91 | assert((!Val || !MustExtend) && "Extension contradiction"); |
| 92 | MustNotExtend = Val; |
| 93 | } |
| 94 | bool HexagonMCExpr::mustNotExtend() const { return MustNotExtend; } |
| 95 | |
Krzysztof Parzyszek | 57a8bb43 | 2017-05-02 18:19:11 +0000 | [diff] [blame] | 96 | bool HexagonMCExpr::s27_2_reloc() const { return S27_2_reloc; } |
| 97 | void HexagonMCExpr::setS27_2_reloc(bool Val) { |
| 98 | S27_2_reloc = Val; |
Colin LeMahieu | ecef1d9 | 2016-02-16 20:38:17 +0000 | [diff] [blame] | 99 | } |
| 100 | |
Colin LeMahieu | 98c8e07 | 2016-02-15 18:42:07 +0000 | [diff] [blame] | 101 | bool HexagonMCExpr::classof(MCExpr const *E) { |
Colin LeMahieu | 7cd0892 | 2015-11-09 04:07:48 +0000 | [diff] [blame] | 102 | return E->getKind() == MCExpr::Target; |
| 103 | } |
| 104 | |
Colin LeMahieu | 98c8e07 | 2016-02-15 18:42:07 +0000 | [diff] [blame] | 105 | HexagonMCExpr::HexagonMCExpr(MCExpr const *Expr) |
Krzysztof Parzyszek | 57a8bb43 | 2017-05-02 18:19:11 +0000 | [diff] [blame] | 106 | : Expr(Expr), MustNotExtend(false), MustExtend(false), S27_2_reloc(false), |
Colin LeMahieu | 9e5a9c3 | 2016-02-29 20:42:25 +0000 | [diff] [blame] | 107 | SignMismatch(false) {} |
Colin LeMahieu | 7cd0892 | 2015-11-09 04:07:48 +0000 | [diff] [blame] | 108 | |
Colin LeMahieu | 98c8e07 | 2016-02-15 18:42:07 +0000 | [diff] [blame] | 109 | void HexagonMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { |
Colin LeMahieu | 7cd0892 | 2015-11-09 04:07:48 +0000 | [diff] [blame] | 110 | Expr->print(OS, MAI); |
| 111 | } |
Colin LeMahieu | b9f1eae | 2016-02-29 19:17:56 +0000 | [diff] [blame] | 112 | |
| 113 | void HexagonMCExpr::setSignMismatch(bool Val) { |
| 114 | SignMismatch = Val; |
| 115 | } |
| 116 | |
| 117 | bool HexagonMCExpr::signMismatch() const { |
| 118 | return SignMismatch; |
Krzysztof Parzyszek | 8cdfe8e | 2017-02-06 19:35:46 +0000 | [diff] [blame] | 119 | } |