LLVM 20.0.0git
SparcMCExpr.cpp
Go to the documentation of this file.
1//===-- SparcMCExpr.cpp - Sparc 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// This file contains the implementation of the assembly expression modifiers
10// accepted by the Sparc architecture (e.g. "%hi", "%lo", ...).
11//
12//===----------------------------------------------------------------------===//
13
14#include "SparcMCExpr.h"
16#include "llvm/MC/MCAssembler.h"
17#include "llvm/MC/MCContext.h"
19#include "llvm/MC/MCSymbolELF.h"
21
22using namespace llvm;
23
24#define DEBUG_TYPE "sparcmcexpr"
25
26const SparcMCExpr*
28 MCContext &Ctx) {
29 return new (Ctx) SparcMCExpr(Kind, Expr);
30}
31
33
34 bool closeParen = printVariantKind(OS, Kind);
35
36 const MCExpr *Expr = getSubExpr();
37 Expr->print(OS, MAI);
38
39 if (closeParen)
40 OS << ')';
41}
42
44{
45 switch (Kind) {
46 case VK_Sparc_None: return false;
47 case VK_Sparc_LO: OS << "%lo("; return true;
48 case VK_Sparc_HI: OS << "%hi("; return true;
49 case VK_Sparc_H44: OS << "%h44("; return true;
50 case VK_Sparc_M44: OS << "%m44("; return true;
51 case VK_Sparc_L44: OS << "%l44("; return true;
52 case VK_Sparc_HH: OS << "%hh("; return true;
53 case VK_Sparc_HM: OS << "%hm("; return true;
54 case VK_Sparc_LM: OS << "%lm("; return true;
55 // FIXME: use %pc22/%pc10, if system assembler supports them.
56 case VK_Sparc_PC22: OS << "%hi("; return true;
57 case VK_Sparc_PC10: OS << "%lo("; return true;
58 // FIXME: use %got22/%got10, if system assembler supports them.
59 case VK_Sparc_GOT22: OS << "%hi("; return true;
60 case VK_Sparc_GOT10: OS << "%lo("; return true;
61 case VK_Sparc_GOT13: return false;
62 case VK_Sparc_13: return false;
63 case VK_Sparc_WDISP30: return false;
64 case VK_Sparc_WPLT30: return false;
65 case VK_Sparc_R_DISP32: OS << "%r_disp32("; return true;
66 case VK_Sparc_TLS_GD_HI22: OS << "%tgd_hi22("; return true;
67 case VK_Sparc_TLS_GD_LO10: OS << "%tgd_lo10("; return true;
68 case VK_Sparc_TLS_GD_ADD: OS << "%tgd_add("; return true;
69 case VK_Sparc_TLS_GD_CALL: OS << "%tgd_call("; return true;
70 case VK_Sparc_TLS_LDM_HI22: OS << "%tldm_hi22("; return true;
71 case VK_Sparc_TLS_LDM_LO10: OS << "%tldm_lo10("; return true;
72 case VK_Sparc_TLS_LDM_ADD: OS << "%tldm_add("; return true;
73 case VK_Sparc_TLS_LDM_CALL: OS << "%tldm_call("; return true;
74 case VK_Sparc_TLS_LDO_HIX22: OS << "%tldo_hix22("; return true;
75 case VK_Sparc_TLS_LDO_LOX10: OS << "%tldo_lox10("; return true;
76 case VK_Sparc_TLS_LDO_ADD: OS << "%tldo_add("; return true;
77 case VK_Sparc_TLS_IE_HI22: OS << "%tie_hi22("; return true;
78 case VK_Sparc_TLS_IE_LO10: OS << "%tie_lo10("; return true;
79 case VK_Sparc_TLS_IE_LD: OS << "%tie_ld("; return true;
80 case VK_Sparc_TLS_IE_LDX: OS << "%tie_ldx("; return true;
81 case VK_Sparc_TLS_IE_ADD: OS << "%tie_add("; return true;
82 case VK_Sparc_TLS_LE_HIX22: OS << "%tle_hix22("; return true;
83 case VK_Sparc_TLS_LE_LOX10: OS << "%tle_lox10("; return true;
84 case VK_Sparc_HIX22: OS << "%hix("; return true;
85 case VK_Sparc_LOX10: OS << "%lox("; return true;
86 case VK_Sparc_GOTDATA_HIX22: OS << "%gdop_hix22("; return true;
87 case VK_Sparc_GOTDATA_LOX10: OS << "%gdop_lox10("; return true;
88 case VK_Sparc_GOTDATA_OP: OS << "%gdop("; return true;
89 }
90 llvm_unreachable("Unhandled SparcMCExpr::VariantKind");
91}
92
94{
96 .Case("lo", VK_Sparc_LO)
97 .Case("hi", VK_Sparc_HI)
98 .Case("h44", VK_Sparc_H44)
99 .Case("m44", VK_Sparc_M44)
100 .Case("l44", VK_Sparc_L44)
101 .Case("hh", VK_Sparc_HH)
102 .Case("uhi", VK_Sparc_HH) // Nonstandard GNU extension
103 .Case("hm", VK_Sparc_HM)
104 .Case("ulo", VK_Sparc_HM) // Nonstandard GNU extension
105 .Case("lm", VK_Sparc_LM)
106 .Case("pc22", VK_Sparc_PC22)
107 .Case("pc10", VK_Sparc_PC10)
108 .Case("got22", VK_Sparc_GOT22)
109 .Case("got10", VK_Sparc_GOT10)
110 .Case("got13", VK_Sparc_GOT13)
111 .Case("r_disp32", VK_Sparc_R_DISP32)
112 .Case("tgd_hi22", VK_Sparc_TLS_GD_HI22)
113 .Case("tgd_lo10", VK_Sparc_TLS_GD_LO10)
114 .Case("tgd_add", VK_Sparc_TLS_GD_ADD)
115 .Case("tgd_call", VK_Sparc_TLS_GD_CALL)
116 .Case("tldm_hi22", VK_Sparc_TLS_LDM_HI22)
117 .Case("tldm_lo10", VK_Sparc_TLS_LDM_LO10)
118 .Case("tldm_add", VK_Sparc_TLS_LDM_ADD)
119 .Case("tldm_call", VK_Sparc_TLS_LDM_CALL)
120 .Case("tldo_hix22", VK_Sparc_TLS_LDO_HIX22)
121 .Case("tldo_lox10", VK_Sparc_TLS_LDO_LOX10)
122 .Case("tldo_add", VK_Sparc_TLS_LDO_ADD)
123 .Case("tie_hi22", VK_Sparc_TLS_IE_HI22)
124 .Case("tie_lo10", VK_Sparc_TLS_IE_LO10)
125 .Case("tie_ld", VK_Sparc_TLS_IE_LD)
126 .Case("tie_ldx", VK_Sparc_TLS_IE_LDX)
127 .Case("tie_add", VK_Sparc_TLS_IE_ADD)
128 .Case("tle_hix22", VK_Sparc_TLS_LE_HIX22)
129 .Case("tle_lox10", VK_Sparc_TLS_LE_LOX10)
130 .Case("hix", VK_Sparc_HIX22)
131 .Case("lox", VK_Sparc_LOX10)
132 .Case("gdop_hix22", VK_Sparc_GOTDATA_HIX22)
133 .Case("gdop_lox10", VK_Sparc_GOTDATA_LOX10)
134 .Case("gdop", VK_Sparc_GOTDATA_OP)
136}
137
139 switch (Kind) {
140 default: llvm_unreachable("Unhandled SparcMCExpr::VariantKind");
180 }
181}
182
184 const MCAssembler *Asm,
185 const MCFixup *Fixup) const {
186 return getSubExpr()->evaluateAsRelocatable(Res, Asm, Fixup);
187}
188
189static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
190 switch (Expr->getKind()) {
191 case MCExpr::Target:
192 llvm_unreachable("Can't handle nested target expr!");
193 break;
194
195 case MCExpr::Constant:
196 break;
197
198 case MCExpr::Binary: {
199 const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
202 break;
203 }
204
205 case MCExpr::SymbolRef: {
206 const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
207 cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS);
208 break;
209 }
210
211 case MCExpr::Unary:
212 fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm);
213 break;
214 }
215
216}
217
219 switch(getKind()) {
220 default: return;
223 // The corresponding relocations reference __tls_get_addr, as they call it,
224 // but this is only implicit; we must explicitly add it to our symbol table
225 // to bind it for these uses.
226 MCSymbol *Symbol = Asm.getContext().getOrCreateSymbol("__tls_get_addr");
227 Asm.registerSymbol(*Symbol);
228 auto ELFSymbol = cast<MCSymbolELF>(Symbol);
229 if (!ELFSymbol->isBindingSet())
230 ELFSymbol->setBinding(ELF::STB_GLOBAL);
231 [[fallthrough]];
232 }
248 case VK_Sparc_TLS_LE_LOX10: break;
249 }
251}
252
254 Streamer.visitUsedExpr(*getSubExpr());
255}
static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm)
PowerPC TLS Dynamic Call Fixup
static const char * name
Definition: SMEABIPass.cpp:50
raw_pwrite_stream & OS
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:56
Binary assembler expressions.
Definition: MCExpr.h:488
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition: MCExpr.h:635
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Definition: MCExpr.h:638
Context object for machine code objects.
Definition: MCContext.h:83
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
@ Unary
Unary expressions.
Definition: MCExpr.h:40
@ Constant
Constant expressions.
Definition: MCExpr.h:38
@ SymbolRef
References to labels and assigned expressions.
Definition: MCExpr.h:39
@ Target
Target specific expression.
Definition: MCExpr.h:41
@ Binary
Binary expressions.
Definition: MCExpr.h:37
bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Definition: MCExpr.cpp:788
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:40
ExprKind getKind() const
Definition: MCExpr.h:78
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
Streaming machine code generation interface.
Definition: MCStreamer.h:213
void visitUsedExpr(const MCExpr &Expr)
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:188
const MCSymbol & getSymbol() const
Definition: MCExpr.h:406
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
This represents an "assembler immediate".
Definition: MCValue.h:36
const MCExpr * getSubExpr() const
getSubExpr - Get the child of this expression.
Definition: SparcMCExpr.h:90
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, const MCFixup *Fixup) const override
static const SparcMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: SparcMCExpr.cpp:27
Sparc::Fixups getFixupKind() const
getFixupKind - Get the fixup kind of this expression.
Definition: SparcMCExpr.h:93
void visitUsedExpr(MCStreamer &Streamer) const override
static VariantKind parseVariantKind(StringRef name)
Definition: SparcMCExpr.cpp:93
static bool printVariantKind(raw_ostream &OS, VariantKind Kind)
Definition: SparcMCExpr.cpp:43
void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override
VariantKind getKind() const
getOpcode - Get the kind of this expression.
Definition: SparcMCExpr.h:87
void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override
Definition: SparcMCExpr.cpp:32
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ STB_GLOBAL
Definition: ELF.h:1340
@ STT_TLS
Definition: ELF.h:1357
@ fixup_sparc_lo10
fixup_sparc_lo10 - 10-bit fixup corresponding to lo(foo)
@ fixup_sparc_lm
fixup_sparc_lm - 22-bit fixup corresponding to lm(foo)
@ fixup_sparc_lox10
13-bit fixup corresponding to lox(foo)
@ fixup_sparc_hi22
fixup_sparc_hi22 - 22-bit fixup corresponding to hi(foo) for sethi
@ fixup_sparc_tls_ldo_lox10
@ fixup_sparc_tls_le_hix22
@ fixup_sparc_m44
fixup_sparc_m44 - 10-bit fixup corresponding to m44(foo)
@ fixup_sparc_gotdata_hix22
22-bit fixup corresponding to gdop_hix22(foo)
@ fixup_sparc_hh
fixup_sparc_hh - 22-bit fixup corresponding to hh(foo)
@ fixup_sparc_got10
fixup_sparc_got10 - 10-bit fixup corresponding to got10(foo)
@ fixup_sparc_tls_le_lox10
@ fixup_sparc_got13
fixup_sparc_got13 - 13-bit fixup corresponding to got13(foo)
@ fixup_sparc_tls_ldo_hix22
@ fixup_sparc_gotdata_op
32-bit fixup corresponding to gdop(foo)
@ fixup_sparc_tls_gd_hi22
fixups for Thread Local Storage
@ fixup_sparc_13
fixup_sparc_13 - 13-bit fixup
@ fixup_sparc_hix22
22-bit fixup corresponding to hix(foo)
@ fixup_sparc_got22
fixup_sparc_got22 - 22-bit fixup corresponding to got22(foo)
@ fixup_sparc_h44
fixup_sparc_h44 - 22-bit fixup corresponding to h44(foo)
@ fixup_sparc_tls_ldm_lo10
@ fixup_sparc_tls_ldm_call
@ fixup_sparc_pc22
fixup_sparc_pc22 - 22-bit fixup corresponding to pc22(foo)
@ fixup_sparc_tls_ldm_hi22
@ fixup_sparc_l44
fixup_sparc_l44 - 12-bit fixup corresponding to l44(foo)
@ fixup_sparc_gotdata_lox10
13-bit fixup corresponding to gdop_lox10(foo)
@ fixup_sparc_pc10
fixup_sparc_pc10 - 10-bit fixup corresponding to pc10(foo)
@ fixup_sparc_hm
fixup_sparc_hm - 10-bit fixup corresponding to hm(foo)
@ fixup_sparc_wplt30
fixup_sparc_wplt30
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18