xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/VE/MCTargetDesc/VEMCExpr.cpp (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
1*5ffd83dbSDimitry Andric //===-- VEMCExpr.cpp - VE specific MC expression classes ------------------===//
2*5ffd83dbSDimitry Andric //
3*5ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*5ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*5ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*5ffd83dbSDimitry Andric //
7*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
8*5ffd83dbSDimitry Andric //
9*5ffd83dbSDimitry Andric // This file contains the implementation of the assembly expression modifiers
10*5ffd83dbSDimitry Andric // accepted by the VE architecture (e.g. "%hi", "%lo", ...).
11*5ffd83dbSDimitry Andric //
12*5ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
13*5ffd83dbSDimitry Andric 
14*5ffd83dbSDimitry Andric #include "VEMCExpr.h"
15*5ffd83dbSDimitry Andric #include "llvm/MC/MCAssembler.h"
16*5ffd83dbSDimitry Andric #include "llvm/MC/MCContext.h"
17*5ffd83dbSDimitry Andric #include "llvm/MC/MCObjectStreamer.h"
18*5ffd83dbSDimitry Andric #include "llvm/MC/MCSymbolELF.h"
19*5ffd83dbSDimitry Andric #include "llvm/BinaryFormat/ELF.h"
20*5ffd83dbSDimitry Andric 
21*5ffd83dbSDimitry Andric using namespace llvm;
22*5ffd83dbSDimitry Andric 
23*5ffd83dbSDimitry Andric #define DEBUG_TYPE "vemcexpr"
24*5ffd83dbSDimitry Andric 
25*5ffd83dbSDimitry Andric const VEMCExpr *VEMCExpr::create(VariantKind Kind, const MCExpr *Expr,
26*5ffd83dbSDimitry Andric                                  MCContext &Ctx) {
27*5ffd83dbSDimitry Andric   return new (Ctx) VEMCExpr(Kind, Expr);
28*5ffd83dbSDimitry Andric }
29*5ffd83dbSDimitry Andric 
30*5ffd83dbSDimitry Andric void VEMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
31*5ffd83dbSDimitry Andric 
32*5ffd83dbSDimitry Andric   bool closeParen = printVariantKind(OS, Kind);
33*5ffd83dbSDimitry Andric 
34*5ffd83dbSDimitry Andric   const MCExpr *Expr = getSubExpr();
35*5ffd83dbSDimitry Andric   Expr->print(OS, MAI);
36*5ffd83dbSDimitry Andric 
37*5ffd83dbSDimitry Andric   if (closeParen)
38*5ffd83dbSDimitry Andric     OS << ')';
39*5ffd83dbSDimitry Andric   printVariantKindSuffix(OS, Kind);
40*5ffd83dbSDimitry Andric }
41*5ffd83dbSDimitry Andric 
42*5ffd83dbSDimitry Andric bool VEMCExpr::printVariantKind(raw_ostream &OS, VariantKind Kind) {
43*5ffd83dbSDimitry Andric   switch (Kind) {
44*5ffd83dbSDimitry Andric   case VK_VE_None:
45*5ffd83dbSDimitry Andric   case VK_VE_REFLONG:
46*5ffd83dbSDimitry Andric     return false;
47*5ffd83dbSDimitry Andric 
48*5ffd83dbSDimitry Andric   case VK_VE_HI32:
49*5ffd83dbSDimitry Andric   case VK_VE_LO32:
50*5ffd83dbSDimitry Andric   case VK_VE_PC_HI32:
51*5ffd83dbSDimitry Andric   case VK_VE_PC_LO32:
52*5ffd83dbSDimitry Andric   case VK_VE_GOT_HI32:
53*5ffd83dbSDimitry Andric   case VK_VE_GOT_LO32:
54*5ffd83dbSDimitry Andric   case VK_VE_GOTOFF_HI32:
55*5ffd83dbSDimitry Andric   case VK_VE_GOTOFF_LO32:
56*5ffd83dbSDimitry Andric   case VK_VE_PLT_HI32:
57*5ffd83dbSDimitry Andric   case VK_VE_PLT_LO32:
58*5ffd83dbSDimitry Andric   case VK_VE_TLS_GD_HI32:
59*5ffd83dbSDimitry Andric   case VK_VE_TLS_GD_LO32:
60*5ffd83dbSDimitry Andric   case VK_VE_TPOFF_HI32:
61*5ffd83dbSDimitry Andric   case VK_VE_TPOFF_LO32:
62*5ffd83dbSDimitry Andric     // Use suffix for these variant kinds
63*5ffd83dbSDimitry Andric     return false;
64*5ffd83dbSDimitry Andric   }
65*5ffd83dbSDimitry Andric   return true;
66*5ffd83dbSDimitry Andric }
67*5ffd83dbSDimitry Andric 
68*5ffd83dbSDimitry Andric void VEMCExpr::printVariantKindSuffix(raw_ostream &OS, VariantKind Kind) {
69*5ffd83dbSDimitry Andric   switch (Kind) {
70*5ffd83dbSDimitry Andric   case VK_VE_None:
71*5ffd83dbSDimitry Andric   case VK_VE_REFLONG:
72*5ffd83dbSDimitry Andric     break;
73*5ffd83dbSDimitry Andric   case VK_VE_HI32:
74*5ffd83dbSDimitry Andric     OS << "@hi";
75*5ffd83dbSDimitry Andric     break;
76*5ffd83dbSDimitry Andric   case VK_VE_LO32:
77*5ffd83dbSDimitry Andric     OS << "@lo";
78*5ffd83dbSDimitry Andric     break;
79*5ffd83dbSDimitry Andric   case VK_VE_PC_HI32:
80*5ffd83dbSDimitry Andric     OS << "@pc_hi";
81*5ffd83dbSDimitry Andric     break;
82*5ffd83dbSDimitry Andric   case VK_VE_PC_LO32:
83*5ffd83dbSDimitry Andric     OS << "@pc_lo";
84*5ffd83dbSDimitry Andric     break;
85*5ffd83dbSDimitry Andric   case VK_VE_GOT_HI32:
86*5ffd83dbSDimitry Andric     OS << "@got_hi";
87*5ffd83dbSDimitry Andric     break;
88*5ffd83dbSDimitry Andric   case VK_VE_GOT_LO32:
89*5ffd83dbSDimitry Andric     OS << "@got_lo";
90*5ffd83dbSDimitry Andric     break;
91*5ffd83dbSDimitry Andric   case VK_VE_GOTOFF_HI32:
92*5ffd83dbSDimitry Andric     OS << "@gotoff_hi";
93*5ffd83dbSDimitry Andric     break;
94*5ffd83dbSDimitry Andric   case VK_VE_GOTOFF_LO32:
95*5ffd83dbSDimitry Andric     OS << "@gotoff_lo";
96*5ffd83dbSDimitry Andric     break;
97*5ffd83dbSDimitry Andric   case VK_VE_PLT_HI32:
98*5ffd83dbSDimitry Andric     OS << "@plt_hi";
99*5ffd83dbSDimitry Andric     break;
100*5ffd83dbSDimitry Andric   case VK_VE_PLT_LO32:
101*5ffd83dbSDimitry Andric     OS << "@plt_lo";
102*5ffd83dbSDimitry Andric     break;
103*5ffd83dbSDimitry Andric   case VK_VE_TLS_GD_HI32:
104*5ffd83dbSDimitry Andric     OS << "@tls_gd_hi";
105*5ffd83dbSDimitry Andric     break;
106*5ffd83dbSDimitry Andric   case VK_VE_TLS_GD_LO32:
107*5ffd83dbSDimitry Andric     OS << "@tls_gd_lo";
108*5ffd83dbSDimitry Andric     break;
109*5ffd83dbSDimitry Andric   case VK_VE_TPOFF_HI32:
110*5ffd83dbSDimitry Andric     OS << "@tpoff_hi";
111*5ffd83dbSDimitry Andric     break;
112*5ffd83dbSDimitry Andric   case VK_VE_TPOFF_LO32:
113*5ffd83dbSDimitry Andric     OS << "@tpoff_lo";
114*5ffd83dbSDimitry Andric     break;
115*5ffd83dbSDimitry Andric   }
116*5ffd83dbSDimitry Andric }
117*5ffd83dbSDimitry Andric 
118*5ffd83dbSDimitry Andric VEMCExpr::VariantKind VEMCExpr::parseVariantKind(StringRef name) {
119*5ffd83dbSDimitry Andric   return StringSwitch<VEMCExpr::VariantKind>(name)
120*5ffd83dbSDimitry Andric       .Case("hi", VK_VE_HI32)
121*5ffd83dbSDimitry Andric       .Case("lo", VK_VE_LO32)
122*5ffd83dbSDimitry Andric       .Case("pc_hi", VK_VE_PC_HI32)
123*5ffd83dbSDimitry Andric       .Case("pc_lo", VK_VE_PC_LO32)
124*5ffd83dbSDimitry Andric       .Case("got_hi", VK_VE_GOT_HI32)
125*5ffd83dbSDimitry Andric       .Case("got_lo", VK_VE_GOT_LO32)
126*5ffd83dbSDimitry Andric       .Case("gotoff_hi", VK_VE_GOTOFF_HI32)
127*5ffd83dbSDimitry Andric       .Case("gotoff_lo", VK_VE_GOTOFF_LO32)
128*5ffd83dbSDimitry Andric       .Case("plt_hi", VK_VE_PLT_HI32)
129*5ffd83dbSDimitry Andric       .Case("plt_lo", VK_VE_PLT_LO32)
130*5ffd83dbSDimitry Andric       .Case("tls_gd_hi", VK_VE_TLS_GD_HI32)
131*5ffd83dbSDimitry Andric       .Case("tls_gd_lo", VK_VE_TLS_GD_LO32)
132*5ffd83dbSDimitry Andric       .Case("tpoff_hi", VK_VE_TPOFF_HI32)
133*5ffd83dbSDimitry Andric       .Case("tpoff_lo", VK_VE_TPOFF_LO32)
134*5ffd83dbSDimitry Andric       .Default(VK_VE_None);
135*5ffd83dbSDimitry Andric }
136*5ffd83dbSDimitry Andric 
137*5ffd83dbSDimitry Andric VE::Fixups VEMCExpr::getFixupKind(VEMCExpr::VariantKind Kind) {
138*5ffd83dbSDimitry Andric   switch (Kind) {
139*5ffd83dbSDimitry Andric   default:
140*5ffd83dbSDimitry Andric     llvm_unreachable("Unhandled VEMCExpr::VariantKind");
141*5ffd83dbSDimitry Andric   case VK_VE_REFLONG:
142*5ffd83dbSDimitry Andric     return VE::fixup_ve_reflong;
143*5ffd83dbSDimitry Andric   case VK_VE_HI32:
144*5ffd83dbSDimitry Andric     return VE::fixup_ve_hi32;
145*5ffd83dbSDimitry Andric   case VK_VE_LO32:
146*5ffd83dbSDimitry Andric     return VE::fixup_ve_lo32;
147*5ffd83dbSDimitry Andric   case VK_VE_PC_HI32:
148*5ffd83dbSDimitry Andric     return VE::fixup_ve_pc_hi32;
149*5ffd83dbSDimitry Andric   case VK_VE_PC_LO32:
150*5ffd83dbSDimitry Andric     return VE::fixup_ve_pc_lo32;
151*5ffd83dbSDimitry Andric   case VK_VE_GOT_HI32:
152*5ffd83dbSDimitry Andric     return VE::fixup_ve_got_hi32;
153*5ffd83dbSDimitry Andric   case VK_VE_GOT_LO32:
154*5ffd83dbSDimitry Andric     return VE::fixup_ve_got_lo32;
155*5ffd83dbSDimitry Andric   case VK_VE_GOTOFF_HI32:
156*5ffd83dbSDimitry Andric     return VE::fixup_ve_gotoff_hi32;
157*5ffd83dbSDimitry Andric   case VK_VE_GOTOFF_LO32:
158*5ffd83dbSDimitry Andric     return VE::fixup_ve_gotoff_lo32;
159*5ffd83dbSDimitry Andric   case VK_VE_PLT_HI32:
160*5ffd83dbSDimitry Andric     return VE::fixup_ve_plt_hi32;
161*5ffd83dbSDimitry Andric   case VK_VE_PLT_LO32:
162*5ffd83dbSDimitry Andric     return VE::fixup_ve_plt_lo32;
163*5ffd83dbSDimitry Andric   case VK_VE_TLS_GD_HI32:
164*5ffd83dbSDimitry Andric     return VE::fixup_ve_tls_gd_hi32;
165*5ffd83dbSDimitry Andric   case VK_VE_TLS_GD_LO32:
166*5ffd83dbSDimitry Andric     return VE::fixup_ve_tls_gd_lo32;
167*5ffd83dbSDimitry Andric   case VK_VE_TPOFF_HI32:
168*5ffd83dbSDimitry Andric     return VE::fixup_ve_tpoff_hi32;
169*5ffd83dbSDimitry Andric   case VK_VE_TPOFF_LO32:
170*5ffd83dbSDimitry Andric     return VE::fixup_ve_tpoff_lo32;
171*5ffd83dbSDimitry Andric   }
172*5ffd83dbSDimitry Andric }
173*5ffd83dbSDimitry Andric 
174*5ffd83dbSDimitry Andric bool VEMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
175*5ffd83dbSDimitry Andric                                          const MCAsmLayout *Layout,
176*5ffd83dbSDimitry Andric                                          const MCFixup *Fixup) const {
177*5ffd83dbSDimitry Andric   return getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup);
178*5ffd83dbSDimitry Andric }
179*5ffd83dbSDimitry Andric 
180*5ffd83dbSDimitry Andric static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
181*5ffd83dbSDimitry Andric   switch (Expr->getKind()) {
182*5ffd83dbSDimitry Andric   case MCExpr::Target:
183*5ffd83dbSDimitry Andric     llvm_unreachable("Can't handle nested target expr!");
184*5ffd83dbSDimitry Andric     break;
185*5ffd83dbSDimitry Andric 
186*5ffd83dbSDimitry Andric   case MCExpr::Constant:
187*5ffd83dbSDimitry Andric     break;
188*5ffd83dbSDimitry Andric 
189*5ffd83dbSDimitry Andric   case MCExpr::Binary: {
190*5ffd83dbSDimitry Andric     const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
191*5ffd83dbSDimitry Andric     fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm);
192*5ffd83dbSDimitry Andric     fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm);
193*5ffd83dbSDimitry Andric     break;
194*5ffd83dbSDimitry Andric   }
195*5ffd83dbSDimitry Andric 
196*5ffd83dbSDimitry Andric   case MCExpr::SymbolRef: {
197*5ffd83dbSDimitry Andric     // We're known to be under a TLS fixup, so any symbol should be
198*5ffd83dbSDimitry Andric     // modified. There should be only one.
199*5ffd83dbSDimitry Andric     const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
200*5ffd83dbSDimitry Andric     cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS);
201*5ffd83dbSDimitry Andric     break;
202*5ffd83dbSDimitry Andric   }
203*5ffd83dbSDimitry Andric 
204*5ffd83dbSDimitry Andric   case MCExpr::Unary:
205*5ffd83dbSDimitry Andric     fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm);
206*5ffd83dbSDimitry Andric     break;
207*5ffd83dbSDimitry Andric   }
208*5ffd83dbSDimitry Andric }
209*5ffd83dbSDimitry Andric 
210*5ffd83dbSDimitry Andric void VEMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
211*5ffd83dbSDimitry Andric   Streamer.visitUsedExpr(*getSubExpr());
212*5ffd83dbSDimitry Andric }
213*5ffd83dbSDimitry Andric 
214*5ffd83dbSDimitry Andric void VEMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
215*5ffd83dbSDimitry Andric   switch (getKind()) {
216*5ffd83dbSDimitry Andric   default:
217*5ffd83dbSDimitry Andric     return;
218*5ffd83dbSDimitry Andric   case VK_VE_TLS_GD_HI32:
219*5ffd83dbSDimitry Andric   case VK_VE_TLS_GD_LO32:
220*5ffd83dbSDimitry Andric   case VK_VE_TPOFF_HI32:
221*5ffd83dbSDimitry Andric   case VK_VE_TPOFF_LO32:
222*5ffd83dbSDimitry Andric     break;
223*5ffd83dbSDimitry Andric   }
224*5ffd83dbSDimitry Andric   fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);
225*5ffd83dbSDimitry Andric }
226