LLVM 23.0.0git
AVRMCAsmInfo.cpp
Go to the documentation of this file.
1//===-- AVRMCAsmInfo.cpp - AVR asm properties -----------------------------===//
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 declarations of the AVRMCAsmInfo properties.
10//
11//===----------------------------------------------------------------------===//
12
13#include "AVRMCAsmInfo.h"
14#include "llvm/MC/MCAssembler.h"
15#include "llvm/MC/MCContext.h"
16#include "llvm/MC/MCExpr.h"
17#include "llvm/MC/MCValue.h"
19
20using namespace llvm;
21
31
32namespace {
33const struct ModifierEntry {
34 const char *const Spelling;
35 AVRMCExpr::Specifier specifier;
36} ModifierNames[] = {
37 {"lo8", AVR::S_LO8}, {"hi8", AVR::S_HI8},
38 {"hh8", AVR::S_HH8}, // synonym with hlo8
39 {"hlo8", AVR::S_HH8}, {"hhi8", AVR::S_HHI8},
40
41 {"pm", AVR::S_PM}, {"pm_lo8", AVR::S_PM_LO8},
42 {"pm_hi8", AVR::S_PM_HI8}, {"pm_hh8", AVR::S_PM_HH8},
43
44 {"lo8_gs", AVR::S_LO8_GS}, {"hi8_gs", AVR::S_HI8_GS},
45 {"gs", AVR::S_GS},
46};
47
48} // end of anonymous namespace
49
51 const auto &Modifier =
52 llvm::find_if(ModifierNames, [&Name](ModifierEntry const &Mod) {
53 return Mod.Spelling == Name;
54 });
55
56 if (Modifier != std::end(ModifierNames)) {
57 return Modifier->specifier;
58 }
59 return AVR::S_AVR_NONE;
60}
61
62const char *AVRMCExpr::getName() const {
63 const auto &Modifier =
64 llvm::find_if(ModifierNames, [this](ModifierEntry const &Mod) {
65 return Mod.specifier == getSpecifier();
66 });
67
68 if (Modifier != std::end(ModifierNames)) {
69 return Modifier->Spelling;
70 }
71 return nullptr;
72}
73
76
77 switch (getSpecifier()) {
78 case AVR::S_LO8:
80 break;
81 case AVR::S_HI8:
83 break;
84 case AVR::S_HH8:
86 break;
87 case AVR::S_HHI8:
89 break;
90
91 case AVR::S_PM_LO8:
93 break;
94 case AVR::S_PM_HI8:
96 break;
97 case AVR::S_PM_HH8:
99 break;
100 case AVR::S_PM:
101 case AVR::S_GS:
102 Kind = AVR::fixup_16_pm;
103 break;
104 case AVR::S_LO8_GS:
106 break;
107 case AVR::S_HI8_GS:
109 break;
110
111 default:
112 llvm_unreachable("Uninitialized expression");
113 }
114
115 return Kind;
116}
117
119 const MCSpecifierExpr &Expr) const {
120 auto &E = static_cast<const AVRMCExpr &>(Expr);
121 assert(E.getSpecifier() != AVR::S_AVR_NONE);
122 OS << E.getName() << '(';
123 if (E.isNegated())
124 OS << '-' << '(';
125 printExpr(OS, *E.getSubExpr());
126 if (E.isNegated())
127 OS << ')';
128 OS << ')';
129}
130
131int64_t AVRMCExpr::evaluateAsInt64(int64_t Value) const {
132 if (Negated)
133 Value *= -1;
134
135 switch (getSpecifier()) {
136 case AVR::S_LO8:
137 Value &= 0xff;
138 break;
139 case AVR::S_HI8:
140 Value &= 0xff00;
141 Value >>= 8;
142 break;
143 case AVR::S_HH8:
144 Value &= 0xff0000;
145 Value >>= 16;
146 break;
147 case AVR::S_HHI8:
148 Value &= 0xff000000;
149 Value >>= 24;
150 break;
151 case AVR::S_PM_LO8:
152 case AVR::S_LO8_GS:
153 Value >>= 1; // Program memory addresses must always be shifted by one.
154 Value &= 0xff;
155 break;
156 case AVR::S_PM_HI8:
157 case AVR::S_HI8_GS:
158 Value >>= 1; // Program memory addresses must always be shifted by one.
159 Value &= 0xff00;
160 Value >>= 8;
161 break;
162 case AVR::S_PM_HH8:
163 Value >>= 1; // Program memory addresses must always be shifted by one.
164 Value &= 0xff0000;
165 Value >>= 16;
166 break;
167 case AVR::S_PM:
168 case AVR::S_GS:
169 Value >>= 1; // Program memory addresses must always be shifted by one.
170 break;
171
172 case AVR::S_AVR_NONE:
173 default:
174 llvm_unreachable("Uninitialized expression.");
175 }
176 return static_cast<uint64_t>(Value) & 0xff;
177}
178
179// bool AVRMCExpr::evaluateAsRelocatableImpl(MCValue &Result,
180// const MCAssembler *Asm) const {
182 MCValue &Result,
183 const MCAssembler *Asm) const {
184 auto &E = static_cast<const AVRMCExpr &>(Expr);
186 bool isRelocatable = E.getSubExpr()->evaluateAsRelocatable(Value, Asm);
187 if (!isRelocatable)
188 return false;
189
190 if (Value.isAbsolute()) {
191 Result = MCValue::get(E.evaluateAsInt64(Value.getConstant()));
192 } else {
193 if (!Asm || !Asm->hasLayout())
194 return false;
195
196 auto Spec = AVR::S_None;
197 if (Value.getSpecifier())
198 return false;
199 assert(!Value.getSubSym());
200 if (E.getSpecifier() == AVR::S_PM)
201 Spec = AVR::S_PM;
202
203 // TODO: don't attach specifier to MCSymbolRefExpr.
204 Result =
205 MCValue::get(Value.getAddSym(), nullptr, Value.getConstant(), Spec);
206 }
207
208 return true;
209}
210
211bool AVRMCExpr::evaluateAsConstant(int64_t &Result) const {
213 bool isRelocatable = getSubExpr()->evaluateAsRelocatable(Value, nullptr);
214 if (!isRelocatable)
215 return false;
216
217 if (Value.isAbsolute()) {
218 Result = evaluateAsInt64(Value.getConstant());
219 return true;
220 }
221
222 return false;
223}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static LVOptions Options
Definition LVOptions.cpp:25
AVRMCAsmInfo(const Triple &TT, const MCTargetOptions &Options)
void printSpecifierExpr(raw_ostream &OS, const MCSpecifierExpr &Expr) const override
bool evaluateAsRelocatableImpl(const MCSpecifierExpr &Expr, MCValue &Res, const MCAssembler *Asm) const override
A expression in AVR machine code.
Definition AVRMCExpr.h:19
bool evaluateAsConstant(int64_t &Result) const
Evaluates the fixup as a constant value.
bool isNegated() const
Definition AVRMCExpr.h:37
const char * getName() const
Gets the name of the expression.
static Specifier parseSpecifier(StringRef Name)
AVR::Fixups getFixupKind() const
Gets the fixup which corresponds to the expression.
MCAsmInfoELF(const MCTargetOptions &Options)
void printExpr(raw_ostream &, const MCExpr &) const
bool UsesELFSectionDirectiveForBSS
This is true if this target uses ELF '.section' directive before the '.bss' one.
Definition MCAsmInfo.h:262
bool SupportsDebugInformation
True if target supports emission of debugging information.
Definition MCAsmInfo.h:358
const char * SeparatorString
This string, if specified, is used to separate instructions from each other when on the same line.
Definition MCAsmInfo.h:131
unsigned CodePointerSize
Code pointer size in bytes. Default is 4.
Definition MCAsmInfo.h:87
unsigned CalleeSaveStackSlotSize
Size of the stack slot reserved for callee-saved registers, in bytes.
Definition MCAsmInfo.h:91
StringRef CommentString
This indicates the comment string used by the assembler.
Definition MCAsmInfo.h:135
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
Definition MCExpr.cpp:450
Extension point for target-specific MCExpr subclasses with a relocation specifier,...
Definition MCExpr.h:495
const MCExpr * getSubExpr() const
Definition MCExpr.h:509
Spec getSpecifier() const
Definition MCExpr.h:508
static MCValue get(const MCSymbol *SymA, const MCSymbol *SymB=nullptr, int64_t Val=0, uint32_t Specifier=0)
Definition MCValue.h:56
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
LLVM Value Representation.
Definition Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Fixups
The set of supported fixups.
@ fixup_16_pm
A 16-bit program memory address.
@ fixup_hh8_ldi
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a 24-bit value ...
@ 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...
@ 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...
@ fixup_ms8_ldi
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a 32-bit value ...
@ fixup_lo8_ldi
Replaces the immediate operand of a 16-bit Rd, K instruction with the lower 8 bits of a 16-bit value ...
@ 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...
@ fixup_hi8_ldi
Replaces the immediate operand of a 16-bit Rd, K instruction with the upper 8 bits of a 16-bit value ...
@ 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...
@ 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...
@ 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...
@ 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...
@ 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...
@ 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...
@ S_LO8
Corresponds to lo8().
@ S_LO8_GS
Corresponds to lo8(gs()).
@ S_HH8
Corresponds to hlo8() and hh8().
@ S_PM_HH8
Corresponds to pm_hh8().
@ S_HHI8
Corresponds to hhi8().
@ S_PM_LO8
Corresponds to pm_lo8().
@ S_PM
Corresponds to pm(), reference to program memory.
@ S_GS
Corresponds to gs().
@ S_HI8_GS
Corresponds to hi8(gs()).
@ S_PM_HI8
Corresponds to pm_hi8().
@ S_HI8
Corresponds to hi8().
This is an optimization pass for GlobalISel generic memory operations.
@ Mod
The access may modify the value stored in memory.
Definition ModRef.h:34
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:1771