1*09467b48Spatrick //===-- MipsMCExpr.cpp - Mips specific MC expression classes --------------===//
2*09467b48Spatrick //
3*09467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*09467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
5*09467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*09467b48Spatrick //
7*09467b48Spatrick //===----------------------------------------------------------------------===//
8*09467b48Spatrick 
9*09467b48Spatrick #include "MipsMCExpr.h"
10*09467b48Spatrick #include "llvm/BinaryFormat/ELF.h"
11*09467b48Spatrick #include "llvm/MC/MCAsmInfo.h"
12*09467b48Spatrick #include "llvm/MC/MCAssembler.h"
13*09467b48Spatrick #include "llvm/MC/MCContext.h"
14*09467b48Spatrick #include "llvm/MC/MCStreamer.h"
15*09467b48Spatrick #include "llvm/MC/MCSymbolELF.h"
16*09467b48Spatrick #include "llvm/MC/MCValue.h"
17*09467b48Spatrick #include "llvm/Support/Casting.h"
18*09467b48Spatrick #include "llvm/Support/ErrorHandling.h"
19*09467b48Spatrick #include "llvm/Support/MathExtras.h"
20*09467b48Spatrick #include "llvm/Support/raw_ostream.h"
21*09467b48Spatrick #include <cstdint>
22*09467b48Spatrick 
23*09467b48Spatrick using namespace llvm;
24*09467b48Spatrick 
25*09467b48Spatrick #define DEBUG_TYPE "mipsmcexpr"
26*09467b48Spatrick 
create(MipsMCExpr::MipsExprKind Kind,const MCExpr * Expr,MCContext & Ctx)27*09467b48Spatrick const MipsMCExpr *MipsMCExpr::create(MipsMCExpr::MipsExprKind Kind,
28*09467b48Spatrick                                      const MCExpr *Expr, MCContext &Ctx) {
29*09467b48Spatrick   return new (Ctx) MipsMCExpr(Kind, Expr);
30*09467b48Spatrick }
31*09467b48Spatrick 
createGpOff(MipsMCExpr::MipsExprKind Kind,const MCExpr * Expr,MCContext & Ctx)32*09467b48Spatrick const MipsMCExpr *MipsMCExpr::createGpOff(MipsMCExpr::MipsExprKind Kind,
33*09467b48Spatrick                                           const MCExpr *Expr, MCContext &Ctx) {
34*09467b48Spatrick   return create(Kind, create(MEK_NEG, create(MEK_GPREL, Expr, Ctx), Ctx), Ctx);
35*09467b48Spatrick }
36*09467b48Spatrick 
printImpl(raw_ostream & OS,const MCAsmInfo * MAI) const37*09467b48Spatrick void MipsMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
38*09467b48Spatrick   int64_t AbsVal;
39*09467b48Spatrick 
40*09467b48Spatrick   switch (Kind) {
41*09467b48Spatrick   case MEK_None:
42*09467b48Spatrick   case MEK_Special:
43*09467b48Spatrick     llvm_unreachable("MEK_None and MEK_Special are invalid");
44*09467b48Spatrick     break;
45*09467b48Spatrick   case MEK_DTPREL:
46*09467b48Spatrick     // MEK_DTPREL is used for marking TLS DIEExpr only
47*09467b48Spatrick     // and contains a regular sub-expression.
48*09467b48Spatrick     getSubExpr()->print(OS, MAI, true);
49*09467b48Spatrick     return;
50*09467b48Spatrick   case MEK_CALL_HI16:
51*09467b48Spatrick     OS << "%call_hi";
52*09467b48Spatrick     break;
53*09467b48Spatrick   case MEK_CALL_LO16:
54*09467b48Spatrick     OS << "%call_lo";
55*09467b48Spatrick     break;
56*09467b48Spatrick   case MEK_DTPREL_HI:
57*09467b48Spatrick     OS << "%dtprel_hi";
58*09467b48Spatrick     break;
59*09467b48Spatrick   case MEK_DTPREL_LO:
60*09467b48Spatrick     OS << "%dtprel_lo";
61*09467b48Spatrick     break;
62*09467b48Spatrick   case MEK_GOT:
63*09467b48Spatrick     OS << "%got";
64*09467b48Spatrick     break;
65*09467b48Spatrick   case MEK_GOTTPREL:
66*09467b48Spatrick     OS << "%gottprel";
67*09467b48Spatrick     break;
68*09467b48Spatrick   case MEK_GOT_CALL:
69*09467b48Spatrick     OS << "%call16";
70*09467b48Spatrick     break;
71*09467b48Spatrick   case MEK_GOT_DISP:
72*09467b48Spatrick     OS << "%got_disp";
73*09467b48Spatrick     break;
74*09467b48Spatrick   case MEK_GOT_HI16:
75*09467b48Spatrick     OS << "%got_hi";
76*09467b48Spatrick     break;
77*09467b48Spatrick   case MEK_GOT_LO16:
78*09467b48Spatrick     OS << "%got_lo";
79*09467b48Spatrick     break;
80*09467b48Spatrick   case MEK_GOT_PAGE:
81*09467b48Spatrick     OS << "%got_page";
82*09467b48Spatrick     break;
83*09467b48Spatrick   case MEK_GOT_OFST:
84*09467b48Spatrick     OS << "%got_ofst";
85*09467b48Spatrick     break;
86*09467b48Spatrick   case MEK_GPREL:
87*09467b48Spatrick     OS << "%gp_rel";
88*09467b48Spatrick     break;
89*09467b48Spatrick   case MEK_HI:
90*09467b48Spatrick     OS << "%hi";
91*09467b48Spatrick     break;
92*09467b48Spatrick   case MEK_HIGHER:
93*09467b48Spatrick     OS << "%higher";
94*09467b48Spatrick     break;
95*09467b48Spatrick   case MEK_HIGHEST:
96*09467b48Spatrick     OS << "%highest";
97*09467b48Spatrick     break;
98*09467b48Spatrick   case MEK_LO:
99*09467b48Spatrick     OS << "%lo";
100*09467b48Spatrick     break;
101*09467b48Spatrick   case MEK_NEG:
102*09467b48Spatrick     OS << "%neg";
103*09467b48Spatrick     break;
104*09467b48Spatrick   case MEK_PCREL_HI16:
105*09467b48Spatrick     OS << "%pcrel_hi";
106*09467b48Spatrick     break;
107*09467b48Spatrick   case MEK_PCREL_LO16:
108*09467b48Spatrick     OS << "%pcrel_lo";
109*09467b48Spatrick     break;
110*09467b48Spatrick   case MEK_TLSGD:
111*09467b48Spatrick     OS << "%tlsgd";
112*09467b48Spatrick     break;
113*09467b48Spatrick   case MEK_TLSLDM:
114*09467b48Spatrick     OS << "%tlsldm";
115*09467b48Spatrick     break;
116*09467b48Spatrick   case MEK_TPREL_HI:
117*09467b48Spatrick     OS << "%tprel_hi";
118*09467b48Spatrick     break;
119*09467b48Spatrick   case MEK_TPREL_LO:
120*09467b48Spatrick     OS << "%tprel_lo";
121*09467b48Spatrick     break;
122*09467b48Spatrick   }
123*09467b48Spatrick 
124*09467b48Spatrick   OS << '(';
125*09467b48Spatrick   if (Expr->evaluateAsAbsolute(AbsVal))
126*09467b48Spatrick     OS << AbsVal;
127*09467b48Spatrick   else
128*09467b48Spatrick     Expr->print(OS, MAI, true);
129*09467b48Spatrick   OS << ')';
130*09467b48Spatrick }
131*09467b48Spatrick 
132*09467b48Spatrick bool
evaluateAsRelocatableImpl(MCValue & Res,const MCAsmLayout * Layout,const MCFixup * Fixup) const133*09467b48Spatrick MipsMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
134*09467b48Spatrick                                       const MCAsmLayout *Layout,
135*09467b48Spatrick                                       const MCFixup *Fixup) const {
136*09467b48Spatrick   // Look for the %hi(%neg(%gp_rel(X))) and %lo(%neg(%gp_rel(X))) special cases.
137*09467b48Spatrick   if (isGpOff()) {
138*09467b48Spatrick     const MCExpr *SubExpr =
139*09467b48Spatrick         cast<MipsMCExpr>(cast<MipsMCExpr>(getSubExpr())->getSubExpr())
140*09467b48Spatrick             ->getSubExpr();
141*09467b48Spatrick     if (!SubExpr->evaluateAsRelocatable(Res, Layout, Fixup))
142*09467b48Spatrick       return false;
143*09467b48Spatrick 
144*09467b48Spatrick     Res = MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(),
145*09467b48Spatrick                        MEK_Special);
146*09467b48Spatrick     return true;
147*09467b48Spatrick   }
148*09467b48Spatrick 
149*09467b48Spatrick   if (!getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup))
150*09467b48Spatrick     return false;
151*09467b48Spatrick 
152*09467b48Spatrick   if (Res.getRefKind() != MCSymbolRefExpr::VK_None)
153*09467b48Spatrick     return false;
154*09467b48Spatrick 
155*09467b48Spatrick   // evaluateAsAbsolute() and evaluateAsValue() require that we evaluate the
156*09467b48Spatrick   // %hi/%lo/etc. here. Fixup is a null pointer when either of these is the
157*09467b48Spatrick   // caller.
158*09467b48Spatrick   if (Res.isAbsolute() && Fixup == nullptr) {
159*09467b48Spatrick     int64_t AbsVal = Res.getConstant();
160*09467b48Spatrick     switch (Kind) {
161*09467b48Spatrick     case MEK_None:
162*09467b48Spatrick     case MEK_Special:
163*09467b48Spatrick       llvm_unreachable("MEK_None and MEK_Special are invalid");
164*09467b48Spatrick     case MEK_DTPREL:
165*09467b48Spatrick       // MEK_DTPREL is used for marking TLS DIEExpr only
166*09467b48Spatrick       // and contains a regular sub-expression.
167*09467b48Spatrick       return getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup);
168*09467b48Spatrick     case MEK_DTPREL_HI:
169*09467b48Spatrick     case MEK_DTPREL_LO:
170*09467b48Spatrick     case MEK_GOT:
171*09467b48Spatrick     case MEK_GOTTPREL:
172*09467b48Spatrick     case MEK_GOT_CALL:
173*09467b48Spatrick     case MEK_GOT_DISP:
174*09467b48Spatrick     case MEK_GOT_HI16:
175*09467b48Spatrick     case MEK_GOT_LO16:
176*09467b48Spatrick     case MEK_GOT_OFST:
177*09467b48Spatrick     case MEK_GOT_PAGE:
178*09467b48Spatrick     case MEK_GPREL:
179*09467b48Spatrick     case MEK_PCREL_HI16:
180*09467b48Spatrick     case MEK_PCREL_LO16:
181*09467b48Spatrick     case MEK_TLSGD:
182*09467b48Spatrick     case MEK_TLSLDM:
183*09467b48Spatrick     case MEK_TPREL_HI:
184*09467b48Spatrick     case MEK_TPREL_LO:
185*09467b48Spatrick       return false;
186*09467b48Spatrick     case MEK_LO:
187*09467b48Spatrick     case MEK_CALL_LO16:
188*09467b48Spatrick       AbsVal = SignExtend64<16>(AbsVal);
189*09467b48Spatrick       break;
190*09467b48Spatrick     case MEK_CALL_HI16:
191*09467b48Spatrick     case MEK_HI:
192*09467b48Spatrick       AbsVal = SignExtend64<16>((AbsVal + 0x8000) >> 16);
193*09467b48Spatrick       break;
194*09467b48Spatrick     case MEK_HIGHER:
195*09467b48Spatrick       AbsVal = SignExtend64<16>((AbsVal + 0x80008000LL) >> 32);
196*09467b48Spatrick       break;
197*09467b48Spatrick     case MEK_HIGHEST:
198*09467b48Spatrick       AbsVal = SignExtend64<16>((AbsVal + 0x800080008000LL) >> 48);
199*09467b48Spatrick       break;
200*09467b48Spatrick     case MEK_NEG:
201*09467b48Spatrick       AbsVal = -AbsVal;
202*09467b48Spatrick       break;
203*09467b48Spatrick     }
204*09467b48Spatrick     Res = MCValue::get(AbsVal);
205*09467b48Spatrick     return true;
206*09467b48Spatrick   }
207*09467b48Spatrick 
208*09467b48Spatrick   // We want to defer it for relocatable expressions since the constant is
209*09467b48Spatrick   // applied to the whole symbol value.
210*09467b48Spatrick   //
211*09467b48Spatrick   // The value of getKind() that is given to MCValue is only intended to aid
212*09467b48Spatrick   // debugging when inspecting MCValue objects. It shouldn't be relied upon
213*09467b48Spatrick   // for decision making.
214*09467b48Spatrick   Res =
215*09467b48Spatrick       MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind());
216*09467b48Spatrick 
217*09467b48Spatrick   return true;
218*09467b48Spatrick }
219*09467b48Spatrick 
visitUsedExpr(MCStreamer & Streamer) const220*09467b48Spatrick void MipsMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
221*09467b48Spatrick   Streamer.visitUsedExpr(*getSubExpr());
222*09467b48Spatrick }
223*09467b48Spatrick 
fixELFSymbolsInTLSFixupsImpl(const MCExpr * Expr,MCAssembler & Asm)224*09467b48Spatrick static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
225*09467b48Spatrick   switch (Expr->getKind()) {
226*09467b48Spatrick   case MCExpr::Target:
227*09467b48Spatrick     fixELFSymbolsInTLSFixupsImpl(cast<MipsMCExpr>(Expr)->getSubExpr(), Asm);
228*09467b48Spatrick     break;
229*09467b48Spatrick   case MCExpr::Constant:
230*09467b48Spatrick     break;
231*09467b48Spatrick   case MCExpr::Binary: {
232*09467b48Spatrick     const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
233*09467b48Spatrick     fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm);
234*09467b48Spatrick     fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm);
235*09467b48Spatrick     break;
236*09467b48Spatrick   }
237*09467b48Spatrick   case MCExpr::SymbolRef: {
238*09467b48Spatrick     // We're known to be under a TLS fixup, so any symbol should be
239*09467b48Spatrick     // modified. There should be only one.
240*09467b48Spatrick     const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
241*09467b48Spatrick     cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS);
242*09467b48Spatrick     break;
243*09467b48Spatrick   }
244*09467b48Spatrick   case MCExpr::Unary:
245*09467b48Spatrick     fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm);
246*09467b48Spatrick     break;
247*09467b48Spatrick   }
248*09467b48Spatrick }
249*09467b48Spatrick 
fixELFSymbolsInTLSFixups(MCAssembler & Asm) const250*09467b48Spatrick void MipsMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
251*09467b48Spatrick   switch (getKind()) {
252*09467b48Spatrick   case MEK_None:
253*09467b48Spatrick   case MEK_Special:
254*09467b48Spatrick     llvm_unreachable("MEK_None and MEK_Special are invalid");
255*09467b48Spatrick     break;
256*09467b48Spatrick   case MEK_CALL_HI16:
257*09467b48Spatrick   case MEK_CALL_LO16:
258*09467b48Spatrick   case MEK_GOT:
259*09467b48Spatrick   case MEK_GOT_CALL:
260*09467b48Spatrick   case MEK_GOT_DISP:
261*09467b48Spatrick   case MEK_GOT_HI16:
262*09467b48Spatrick   case MEK_GOT_LO16:
263*09467b48Spatrick   case MEK_GOT_OFST:
264*09467b48Spatrick   case MEK_GOT_PAGE:
265*09467b48Spatrick   case MEK_GPREL:
266*09467b48Spatrick   case MEK_HI:
267*09467b48Spatrick   case MEK_HIGHER:
268*09467b48Spatrick   case MEK_HIGHEST:
269*09467b48Spatrick   case MEK_LO:
270*09467b48Spatrick   case MEK_NEG:
271*09467b48Spatrick   case MEK_PCREL_HI16:
272*09467b48Spatrick   case MEK_PCREL_LO16:
273*09467b48Spatrick     // If we do have nested target-specific expressions, they will be in
274*09467b48Spatrick     // a consecutive chain.
275*09467b48Spatrick     if (const MipsMCExpr *E = dyn_cast<const MipsMCExpr>(getSubExpr()))
276*09467b48Spatrick       E->fixELFSymbolsInTLSFixups(Asm);
277*09467b48Spatrick     break;
278*09467b48Spatrick   case MEK_DTPREL:
279*09467b48Spatrick   case MEK_DTPREL_HI:
280*09467b48Spatrick   case MEK_DTPREL_LO:
281*09467b48Spatrick   case MEK_TLSLDM:
282*09467b48Spatrick   case MEK_TLSGD:
283*09467b48Spatrick   case MEK_GOTTPREL:
284*09467b48Spatrick   case MEK_TPREL_HI:
285*09467b48Spatrick   case MEK_TPREL_LO:
286*09467b48Spatrick     fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);
287*09467b48Spatrick     break;
288*09467b48Spatrick   }
289*09467b48Spatrick }
290*09467b48Spatrick 
isGpOff(MipsExprKind & Kind) const291*09467b48Spatrick bool MipsMCExpr::isGpOff(MipsExprKind &Kind) const {
292*09467b48Spatrick   if (getKind() == MEK_HI || getKind() == MEK_LO) {
293*09467b48Spatrick     if (const MipsMCExpr *S1 = dyn_cast<const MipsMCExpr>(getSubExpr())) {
294*09467b48Spatrick       if (const MipsMCExpr *S2 = dyn_cast<const MipsMCExpr>(S1->getSubExpr())) {
295*09467b48Spatrick         if (S1->getKind() == MEK_NEG && S2->getKind() == MEK_GPREL) {
296*09467b48Spatrick           Kind = getKind();
297*09467b48Spatrick           return true;
298*09467b48Spatrick         }
299*09467b48Spatrick       }
300*09467b48Spatrick     }
301*09467b48Spatrick   }
302*09467b48Spatrick   return false;
303*09467b48Spatrick }
304