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