LLVM 18.0.0git
AVRMCExpr.cpp
Go to the documentation of this file.
1//===-- AVRMCExpr.cpp - AVR 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#include "AVRMCExpr.h"
10
11#include "llvm/MC/MCAsmLayout.h"
12#include "llvm/MC/MCAssembler.h"
13#include "llvm/MC/MCContext.h"
14#include "llvm/MC/MCStreamer.h"
15#include "llvm/MC/MCValue.h"
16
17namespace llvm {
18
19namespace {
20
21const struct ModifierEntry {
22 const char *const Spelling;
23 AVRMCExpr::VariantKind VariantKind;
24} ModifierNames[] = {
26 {"hh8", AVRMCExpr::VK_AVR_HH8}, // synonym with hlo8
28
31
34};
35
36} // end of anonymous namespace
37
39 bool Negated, MCContext &Ctx) {
40 return new (Ctx) AVRMCExpr(Kind, Expr, Negated);
41}
42
43void AVRMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
44 assert(Kind != VK_AVR_None);
45 OS << getName() << '(';
46 if (isNegated())
47 OS << '-' << '(';
48 getSubExpr()->print(OS, MAI);
49 if (isNegated())
50 OS << ')';
51 OS << ')';
52}
53
54bool AVRMCExpr::evaluateAsConstant(int64_t &Result) const {
56
57 bool isRelocatable =
58 getSubExpr()->evaluateAsRelocatable(Value, nullptr, nullptr);
59
60 if (!isRelocatable)
61 return false;
62
63 if (Value.isAbsolute()) {
64 Result = evaluateAsInt64(Value.getConstant());
65 return true;
66 }
67
68 return false;
69}
70
72 const MCAsmLayout *Layout,
73 const MCFixup *Fixup) const {
75 bool isRelocatable = SubExpr->evaluateAsRelocatable(Value, Layout, Fixup);
76
77 if (!isRelocatable)
78 return false;
79
80 if (Value.isAbsolute()) {
81 Result = MCValue::get(evaluateAsInt64(Value.getConstant()));
82 } else {
83 if (!Layout)
84 return false;
85
87 const MCSymbolRefExpr *Sym = Value.getSymA();
88 MCSymbolRefExpr::VariantKind Modifier = Sym->getKind();
89 if (Modifier != MCSymbolRefExpr::VK_None)
90 return false;
91 if (Kind == VK_AVR_PM) {
93 }
94
95 Sym = MCSymbolRefExpr::create(&Sym->getSymbol(), Modifier, Context);
96 Result = MCValue::get(Sym, Value.getSymB(), Value.getConstant());
97 }
98
99 return true;
100}
101
102int64_t AVRMCExpr::evaluateAsInt64(int64_t Value) const {
103 if (Negated)
104 Value *= -1;
105
106 switch (Kind) {
108 Value &= 0xff;
109 break;
111 Value &= 0xff00;
112 Value >>= 8;
113 break;
115 Value &= 0xff0000;
116 Value >>= 16;
117 break;
119 Value &= 0xff000000;
120 Value >>= 24;
121 break;
124 Value >>= 1; // Program memory addresses must always be shifted by one.
125 Value &= 0xff;
126 break;
129 Value >>= 1; // Program memory addresses must always be shifted by one.
130 Value &= 0xff00;
131 Value >>= 8;
132 break;
134 Value >>= 1; // Program memory addresses must always be shifted by one.
135 Value &= 0xff0000;
136 Value >>= 16;
137 break;
140 Value >>= 1; // Program memory addresses must always be shifted by one.
141 break;
142
144 llvm_unreachable("Uninitialized expression.");
145 }
146 return static_cast<uint64_t>(Value) & 0xff;
147}
148
151
152 switch (getKind()) {
153 case VK_AVR_LO8:
155 break;
156 case VK_AVR_HI8:
158 break;
159 case VK_AVR_HH8:
161 break;
162 case VK_AVR_HHI8:
164 break;
165
166 case VK_AVR_PM_LO8:
168 break;
169 case VK_AVR_PM_HI8:
171 break;
172 case VK_AVR_PM_HH8:
174 break;
175 case VK_AVR_PM:
176 case VK_AVR_GS:
177 Kind = AVR::fixup_16_pm;
178 break;
179 case VK_AVR_LO8_GS:
181 break;
182 case VK_AVR_HI8_GS:
184 break;
185
186 case VK_AVR_None:
187 llvm_unreachable("Uninitialized expression");
188 }
189
190 return Kind;
191}
192
194 Streamer.visitUsedExpr(*getSubExpr());
195}
196
197const char *AVRMCExpr::getName() const {
198 const auto &Modifier =
199 llvm::find_if(ModifierNames, [this](ModifierEntry const &Mod) {
200 return Mod.VariantKind == Kind;
201 });
202
203 if (Modifier != std::end(ModifierNames)) {
204 return Modifier->Spelling;
205 }
206 return nullptr;
207}
208
210 const auto &Modifier =
211 llvm::find_if(ModifierNames, [&Name](ModifierEntry const &Mod) {
212 return Mod.Spelling == Name;
213 });
214
215 if (Modifier != std::end(ModifierNames)) {
216 return Modifier->VariantKind;
217 }
218 return VK_AVR_None;
219}
220
221} // end of namespace llvm
std::string Name
Symbol * Sym
Definition: ELF_riscv.cpp:477
LLVMContext & Context
PowerPC TLS Dynamic Call Fixup
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
A expression in AVR machine code.
Definition: AVRMCExpr.h:19
static const AVRMCExpr * create(VariantKind Kind, const MCExpr *Expr, bool isNegated, MCContext &Ctx)
Creates an AVR machine code expression.
Definition: AVRMCExpr.cpp:38
void visitUsedExpr(MCStreamer &streamer) const override
Definition: AVRMCExpr.cpp:193
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const override
Definition: AVRMCExpr.cpp:71
static VariantKind getKindByName(StringRef Name)
Definition: AVRMCExpr.cpp:209
AVR::Fixups getFixupKind() const
Gets the fixup which corresponds to the expression.
Definition: AVRMCExpr.cpp:149
bool evaluateAsConstant(int64_t &Result) const
Evaluates the fixup as a constant value.
Definition: AVRMCExpr.cpp:54
void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override
Definition: AVRMCExpr.cpp:43
VariantKind getKind() const
Gets the type of the expression.
Definition: AVRMCExpr.h:46
const MCExpr * getSubExpr() const
Definition: AVRMCExpr.h:49
VariantKind
Specifies the type of an expression.
Definition: AVRMCExpr.h:22
@ VK_AVR_PM_LO8
Corresponds to pm_lo8().
Definition: AVRMCExpr.h:31
@ VK_AVR_LO8
Corresponds to lo8().
Definition: AVRMCExpr.h:26
@ VK_AVR_PM_HI8
Corresponds to pm_hi8().
Definition: AVRMCExpr.h:32
@ VK_AVR_PM
Corresponds to pm(), reference to program memory.
Definition: AVRMCExpr.h:30
@ VK_AVR_HHI8
Corresponds to hhi8().
Definition: AVRMCExpr.h:28
@ VK_AVR_HI8_GS
Corresponds to hi8(gs()).
Definition: AVRMCExpr.h:36
@ VK_AVR_HH8
Corresponds to hlo8() and hh8().
Definition: AVRMCExpr.h:27
@ VK_AVR_LO8_GS
Corresponds to lo8(gs()).
Definition: AVRMCExpr.h:35
@ VK_AVR_PM_HH8
Corresponds to pm_hh8().
Definition: AVRMCExpr.h:33
@ VK_AVR_GS
Corresponds to gs().
Definition: AVRMCExpr.h:37
@ VK_AVR_HI8
Corresponds to hi8().
Definition: AVRMCExpr.h:25
bool isNegated() const
Definition: AVRMCExpr.h:55
const char * getName() const
Gets the name of the expression.
Definition: AVRMCExpr.cpp:197
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:56
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:28
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
Definition: MCAsmLayout.h:50
MCContext & getContext() const
Definition: MCAssembler.h:321
Context object for machine code objects.
Definition: MCContext.h:76
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
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:802
void print(raw_ostream &OS, const MCAsmInfo *MAI, bool InParens=false) const
Definition: MCExpr.cpp:41
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:212
void visitUsedExpr(const MCExpr &Expr)
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:389
This represents an "assembler immediate".
Definition: MCValue.h:36
static MCValue get(const MCSymbolRefExpr *SymA, const MCSymbolRefExpr *SymB=nullptr, int64_t Val=0, uint32_t RefKind=0)
Definition: MCValue.h:59
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
LLVM Value Representation.
Definition: Value.h:74
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.
Fixups
The set of supported fixups.
Definition: AVRFixupKinds.h:26
@ fixup_16_pm
A 16-bit program memory address.
Definition: AVRFixupKinds.h:46
@ fixup_hh8_ldi
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a 24-bit value ...
Definition: AVRFixupKinds.h:59
@ LastTargetFixupKind
@ fixup_ms8_ldi_neg
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a negated 32-bi...
Definition: AVRFixupKinds.h:75
@ fixup_lo8_ldi_neg
Replaces the immediate operand of a 16-bit Rd, K instruction with the lower 8 bits of a negated 16-bi...
Definition: AVRFixupKinds.h:66
@ fixup_ms8_ldi
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a 32-bit value ...
Definition: AVRFixupKinds.h:62
@ fixup_lo8_ldi
Replaces the immediate operand of a 16-bit Rd, K instruction with the lower 8 bits of a 16-bit value ...
Definition: AVRFixupKinds.h:53
@ fixup_hi8_ldi_pm_neg
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a negated 16-bi...
Definition: AVRFixupKinds.h:96
@ fixup_hi8_ldi
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a 16-bit value ...
Definition: AVRFixupKinds.h:56
@ fixup_lo8_ldi_pm
Replaces the immediate operand of a 16-bit Rd, K instruction with the lower 8 bits of a 16-bit progra...
Definition: AVRFixupKinds.h:79
@ fixup_hh8_ldi_neg
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a negated 24-bi...
Definition: AVRFixupKinds.h:72
@ fixup_hh8_ldi_pm
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a 24-bit progra...
Definition: AVRFixupKinds.h:87
@ fixup_lo8_ldi_pm_neg
Replaces the immediate operand of a 16-bit Rd, K instruction with the lower 8 bits of a negated 16-bi...
Definition: AVRFixupKinds.h:92
@ fixup_hi8_ldi_pm
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a 16-bit progra...
Definition: AVRFixupKinds.h:83
@ fixup_hh8_ldi_pm_neg
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a negated 24-bi...
@ fixup_hi8_ldi_neg
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a negated 16-bi...
Definition: AVRFixupKinds.h:69
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Mod
The access may modify the value stored in memory.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1753