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