LLVM  10.0.0svn
MipsMCExpr.cpp
Go to the documentation of this file.
1 //===-- MipsMCExpr.cpp - Mips 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 
9 #include "MipsMCExpr.h"
10 #include "llvm/BinaryFormat/ELF.h"
11 #include "llvm/MC/MCAsmInfo.h"
12 #include "llvm/MC/MCAssembler.h"
13 #include "llvm/MC/MCContext.h"
14 #include "llvm/MC/MCStreamer.h"
15 #include "llvm/MC/MCSymbolELF.h"
16 #include "llvm/MC/MCValue.h"
17 #include "llvm/Support/Casting.h"
21 #include <cstdint>
22 
23 using namespace llvm;
24 
25 #define DEBUG_TYPE "mipsmcexpr"
26 
28  const MCExpr *Expr, MCContext &Ctx) {
29  return new (Ctx) MipsMCExpr(Kind, Expr);
30 }
31 
33  const MCExpr *Expr, MCContext &Ctx) {
34  return create(Kind, create(MEK_NEG, create(MEK_GPREL, Expr, Ctx), Ctx), Ctx);
35 }
36 
37 void MipsMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
38  int64_t AbsVal;
39 
40  switch (Kind) {
41  case MEK_None:
42  case MEK_Special:
43  llvm_unreachable("MEK_None and MEK_Special are invalid");
44  break;
45  case MEK_DTPREL:
46  // MEK_DTPREL is used for marking TLS DIEExpr only
47  // and contains a regular sub-expression.
48  getSubExpr()->print(OS, MAI, true);
49  return;
50  case MEK_CALL_HI16:
51  OS << "%call_hi";
52  break;
53  case MEK_CALL_LO16:
54  OS << "%call_lo";
55  break;
56  case MEK_DTPREL_HI:
57  OS << "%dtprel_hi";
58  break;
59  case MEK_DTPREL_LO:
60  OS << "%dtprel_lo";
61  break;
62  case MEK_GOT:
63  OS << "%got";
64  break;
65  case MEK_GOTTPREL:
66  OS << "%gottprel";
67  break;
68  case MEK_GOT_CALL:
69  OS << "%call16";
70  break;
71  case MEK_GOT_DISP:
72  OS << "%got_disp";
73  break;
74  case MEK_GOT_HI16:
75  OS << "%got_hi";
76  break;
77  case MEK_GOT_LO16:
78  OS << "%got_lo";
79  break;
80  case MEK_GOT_PAGE:
81  OS << "%got_page";
82  break;
83  case MEK_GOT_OFST:
84  OS << "%got_ofst";
85  break;
86  case MEK_GPREL:
87  OS << "%gp_rel";
88  break;
89  case MEK_HI:
90  OS << "%hi";
91  break;
92  case MEK_HIGHER:
93  OS << "%higher";
94  break;
95  case MEK_HIGHEST:
96  OS << "%highest";
97  break;
98  case MEK_LO:
99  OS << "%lo";
100  break;
101  case MEK_NEG:
102  OS << "%neg";
103  break;
104  case MEK_PCREL_HI16:
105  OS << "%pcrel_hi";
106  break;
107  case MEK_PCREL_LO16:
108  OS << "%pcrel_lo";
109  break;
110  case MEK_TLSGD:
111  OS << "%tlsgd";
112  break;
113  case MEK_TLSLDM:
114  OS << "%tlsldm";
115  break;
116  case MEK_TPREL_HI:
117  OS << "%tprel_hi";
118  break;
119  case MEK_TPREL_LO:
120  OS << "%tprel_lo";
121  break;
122  }
123 
124  OS << '(';
125  if (Expr->evaluateAsAbsolute(AbsVal))
126  OS << AbsVal;
127  else
128  Expr->print(OS, MAI, true);
129  OS << ')';
130 }
131 
132 bool
134  const MCAsmLayout *Layout,
135  const MCFixup *Fixup) const {
136  // Look for the %hi(%neg(%gp_rel(X))) and %lo(%neg(%gp_rel(X))) special cases.
137  if (isGpOff()) {
138  const MCExpr *SubExpr =
139  cast<MipsMCExpr>(cast<MipsMCExpr>(getSubExpr())->getSubExpr())
140  ->getSubExpr();
141  if (!SubExpr->evaluateAsRelocatable(Res, Layout, Fixup))
142  return false;
143 
144  Res = MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(),
145  MEK_Special);
146  return true;
147  }
148 
149  if (!getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup))
150  return false;
151 
153  return false;
154 
155  // evaluateAsAbsolute() and evaluateAsValue() require that we evaluate the
156  // %hi/%lo/etc. here. Fixup is a null pointer when either of these is the
157  // caller.
158  if (Res.isAbsolute() && Fixup == nullptr) {
159  int64_t AbsVal = Res.getConstant();
160  switch (Kind) {
161  case MEK_None:
162  case MEK_Special:
163  llvm_unreachable("MEK_None and MEK_Special are invalid");
164  case MEK_DTPREL:
165  // MEK_DTPREL is used for marking TLS DIEExpr only
166  // and contains a regular sub-expression.
167  return getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup);
168  case MEK_DTPREL_HI:
169  case MEK_DTPREL_LO:
170  case MEK_GOT:
171  case MEK_GOTTPREL:
172  case MEK_GOT_CALL:
173  case MEK_GOT_DISP:
174  case MEK_GOT_HI16:
175  case MEK_GOT_LO16:
176  case MEK_GOT_OFST:
177  case MEK_GOT_PAGE:
178  case MEK_GPREL:
179  case MEK_PCREL_HI16:
180  case MEK_PCREL_LO16:
181  case MEK_TLSGD:
182  case MEK_TLSLDM:
183  case MEK_TPREL_HI:
184  case MEK_TPREL_LO:
185  return false;
186  case MEK_LO:
187  case MEK_CALL_LO16:
188  AbsVal = SignExtend64<16>(AbsVal);
189  break;
190  case MEK_CALL_HI16:
191  case MEK_HI:
192  AbsVal = SignExtend64<16>((AbsVal + 0x8000) >> 16);
193  break;
194  case MEK_HIGHER:
195  AbsVal = SignExtend64<16>((AbsVal + 0x80008000LL) >> 32);
196  break;
197  case MEK_HIGHEST:
198  AbsVal = SignExtend64<16>((AbsVal + 0x800080008000LL) >> 48);
199  break;
200  case MEK_NEG:
201  AbsVal = -AbsVal;
202  break;
203  }
204  Res = MCValue::get(AbsVal);
205  return true;
206  }
207 
208  // We want to defer it for relocatable expressions since the constant is
209  // applied to the whole symbol value.
210  //
211  // The value of getKind() that is given to MCValue is only intended to aid
212  // debugging when inspecting MCValue objects. It shouldn't be relied upon
213  // for decision making.
214  Res = MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind());
215 
216  return true;
217 }
218 
219 void MipsMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
220  Streamer.visitUsedExpr(*getSubExpr());
221 }
222 
224  switch (Expr->getKind()) {
225  case MCExpr::Target:
226  fixELFSymbolsInTLSFixupsImpl(cast<MipsMCExpr>(Expr)->getSubExpr(), Asm);
227  break;
228  case MCExpr::Constant:
229  break;
230  case MCExpr::Binary: {
231  const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
234  break;
235  }
236  case MCExpr::SymbolRef: {
237  // We're known to be under a TLS fixup, so any symbol should be
238  // modified. There should be only one.
239  const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
240  cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS);
241  break;
242  }
243  case MCExpr::Unary:
244  fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm);
245  break;
246  }
247 }
248 
250  switch (getKind()) {
251  case MEK_None:
252  case MEK_Special:
253  llvm_unreachable("MEK_None and MEK_Special are invalid");
254  break;
255  case MEK_CALL_HI16:
256  case MEK_CALL_LO16:
257  case MEK_GOT:
258  case MEK_GOT_CALL:
259  case MEK_GOT_DISP:
260  case MEK_GOT_HI16:
261  case MEK_GOT_LO16:
262  case MEK_GOT_OFST:
263  case MEK_GOT_PAGE:
264  case MEK_GPREL:
265  case MEK_HI:
266  case MEK_HIGHER:
267  case MEK_HIGHEST:
268  case MEK_LO:
269  case MEK_NEG:
270  case MEK_PCREL_HI16:
271  case MEK_PCREL_LO16:
272  // If we do have nested target-specific expressions, they will be in
273  // a consecutive chain.
274  if (const MipsMCExpr *E = dyn_cast<const MipsMCExpr>(getSubExpr()))
275  E->fixELFSymbolsInTLSFixups(Asm);
276  break;
277  case MEK_DTPREL:
278  case MEK_DTPREL_HI:
279  case MEK_DTPREL_LO:
280  case MEK_TLSLDM:
281  case MEK_TLSGD:
282  case MEK_GOTTPREL:
283  case MEK_TPREL_HI:
284  case MEK_TPREL_LO:
286  break;
287  }
288 }
289 
291  if (getKind() == MEK_HI || getKind() == MEK_LO) {
292  if (const MipsMCExpr *S1 = dyn_cast<const MipsMCExpr>(getSubExpr())) {
293  if (const MipsMCExpr *S2 = dyn_cast<const MipsMCExpr>(S1->getSubExpr())) {
294  if (S1->getKind() == MEK_NEG && S2->getKind() == MEK_GPREL) {
295  Kind = getKind();
296  return true;
297  }
298  }
299  }
300  }
301  return false;
302 }
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const override
Definition: MipsMCExpr.cpp:133
This class represents lattice values for constants.
Definition: AllocatorList.h:23
This represents an "assembler immediate".
Definition: MCValue.h:39
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition: MCExpr.h:568
bool isAbsolute() const
Is this an absolute (as opposed to relocatable) value.
Definition: MCValue.h:52
bool isGpOff() const
Definition: MipsMCExpr.h:85
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:77
int64_t getConstant() const
Definition: MCValue.h:46
const MCSymbolRefExpr * getSymB() const
Definition: MCValue.h:48
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:28
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:169
Context object for machine code objects.
Definition: MCContext.h:65
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Definition: MCExpr.cpp:665
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Definition: MCExpr.h:571
MipsExprKind getKind() const
Get the kind of this expression.
Definition: MipsMCExpr.h:64
void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override
Definition: MipsMCExpr.cpp:249
Unary expressions.
Definition: MCExpr.h:41
void visitUsedExpr(MCStreamer &Streamer) const override
Definition: MipsMCExpr.cpp:219
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:56
Streaming machine code generation interface.
Definition: MCStreamer.h:190
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:42
static const MipsMCExpr * createGpOff(MipsExprKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: MipsMCExpr.cpp:32
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm)
Definition: MipsMCExpr.cpp:223
const MCSymbolRefExpr * getSymA() const
Definition: MCValue.h:47
void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override
Definition: MipsMCExpr.cpp:37
Binary assembler expressions.
Definition: MCExpr.h:421
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MCSymbol & getSymbol() const
Definition: MCExpr.h:340
ExprKind getKind() const
Definition: MCExpr.h:68
void visitUsedExpr(const MCExpr &Expr)
Definition: MCStreamer.cpp:987
const MCExpr * getSubExpr() const
Get the child of this expression.
Definition: MipsMCExpr.h:67
static const MipsMCExpr * create(MipsExprKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: MipsMCExpr.cpp:27
static MCValue get(const MCSymbolRefExpr *SymA, const MCSymbolRefExpr *SymB=nullptr, int64_t Val=0, uint32_t RefKind=0)
Definition: MCValue.h:62
References to labels and assigned expressions.
Definition: MCExpr.h:40
uint32_t getRefKind() const
Definition: MCValue.h:49
Constant expressions.
Definition: MCExpr.h:39
Binary expressions.
Definition: MCExpr.h:38
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
Target specific expression.
Definition: MCExpr.h:42