LLVM 22.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
25 CommentString = ";";
26 SeparatorString = "$";
29}
30
31namespace {
32const struct ModifierEntry {
33 const char *const Spelling;
34 AVRMCExpr::Specifier specifier;
35} ModifierNames[] = {
36 {"lo8", AVR::S_LO8}, {"hi8", AVR::S_HI8},
37 {"hh8", AVR::S_HH8}, // synonym with hlo8
38 {"hlo8", AVR::S_HH8}, {"hhi8", AVR::S_HHI8},
39
40 {"pm", AVR::S_PM}, {"pm_lo8", AVR::S_PM_LO8},
41 {"pm_hi8", AVR::S_PM_HI8}, {"pm_hh8", AVR::S_PM_HH8},
42
43 {"lo8_gs", AVR::S_LO8_GS}, {"hi8_gs", AVR::S_HI8_GS},
44 {"gs", AVR::S_GS},
45};
46
47} // end of anonymous namespace
48
50 const auto &Modifier =
51 llvm::find_if(ModifierNames, [&Name](ModifierEntry const &Mod) {
52 return Mod.Spelling == Name;
53 });
54
55 if (Modifier != std::end(ModifierNames)) {
56 return Modifier->specifier;
57 }
58 return AVR::S_AVR_NONE;
59}
60
61const char *AVRMCExpr::getName() const {
62 const auto &Modifier =
63 llvm::find_if(ModifierNames, [this](ModifierEntry const &Mod) {
64 return Mod.specifier == getSpecifier();
65 });
66
67 if (Modifier != std::end(ModifierNames)) {
68 return Modifier->Spelling;
69 }
70 return nullptr;
71}
72
75
76 switch (getSpecifier()) {
77 case AVR::S_LO8:
79 break;
80 case AVR::S_HI8:
82 break;
83 case AVR::S_HH8:
85 break;
86 case AVR::S_HHI8:
88 break;
89
90 case AVR::S_PM_LO8:
92 break;
93 case AVR::S_PM_HI8:
95 break;
96 case AVR::S_PM_HH8:
98 break;
99 case AVR::S_PM:
100 case AVR::S_GS:
101 Kind = AVR::fixup_16_pm;
102 break;
103 case AVR::S_LO8_GS:
105 break;
106 case AVR::S_HI8_GS:
108 break;
109
110 default:
111 llvm_unreachable("Uninitialized expression");
112 }
113
114 return Kind;
115}
116
118 const MCSpecifierExpr &Expr) const {
119 auto &E = static_cast<const AVRMCExpr &>(Expr);
120 assert(E.getSpecifier() != AVR::S_AVR_NONE);
121 OS << E.getName() << '(';
122 if (E.isNegated())
123 OS << '-' << '(';
124 printExpr(OS, *E.getSubExpr());
125 if (E.isNegated())
126 OS << ')';
127 OS << ')';
128}
129
130int64_t AVRMCExpr::evaluateAsInt64(int64_t Value) const {
131 if (Negated)
132 Value *= -1;
133
134 switch (getSpecifier()) {
135 case AVR::S_LO8:
136 Value &= 0xff;
137 break;
138 case AVR::S_HI8:
139 Value &= 0xff00;
140 Value >>= 8;
141 break;
142 case AVR::S_HH8:
143 Value &= 0xff0000;
144 Value >>= 16;
145 break;
146 case AVR::S_HHI8:
147 Value &= 0xff000000;
148 Value >>= 24;
149 break;
150 case AVR::S_PM_LO8:
151 case AVR::S_LO8_GS:
152 Value >>= 1; // Program memory addresses must always be shifted by one.
153 Value &= 0xff;
154 break;
155 case AVR::S_PM_HI8:
156 case AVR::S_HI8_GS:
157 Value >>= 1; // Program memory addresses must always be shifted by one.
158 Value &= 0xff00;
159 Value >>= 8;
160 break;
161 case AVR::S_PM_HH8:
162 Value >>= 1; // Program memory addresses must always be shifted by one.
163 Value &= 0xff0000;
164 Value >>= 16;
165 break;
166 case AVR::S_PM:
167 case AVR::S_GS:
168 Value >>= 1; // Program memory addresses must always be shifted by one.
169 break;
170
171 case AVR::S_AVR_NONE:
172 default:
173 llvm_unreachable("Uninitialized expression.");
174 }
175 return static_cast<uint64_t>(Value) & 0xff;
176}
177
178// bool AVRMCExpr::evaluateAsRelocatableImpl(MCValue &Result,
179// const MCAssembler *Asm) const {
181 MCValue &Result,
182 const MCAssembler *Asm) const {
183 auto &E = static_cast<const AVRMCExpr &>(Expr);
185 bool isRelocatable = E.getSubExpr()->evaluateAsRelocatable(Value, Asm);
186 if (!isRelocatable)
187 return false;
188
189 if (Value.isAbsolute()) {
190 Result = MCValue::get(E.evaluateAsInt64(Value.getConstant()));
191 } else {
192 if (!Asm || !Asm->hasLayout())
193 return false;
194
195 auto Spec = AVR::S_None;
196 if (Value.getSpecifier())
197 return false;
198 assert(!Value.getSubSym());
199 if (E.getSpecifier() == AVR::S_PM)
200 Spec = AVR::S_PM;
201
202 // TODO: don't attach specifier to MCSymbolRefExpr.
203 Result =
204 MCValue::get(Value.getAddSym(), nullptr, Value.getConstant(), Spec);
205 }
206
207 return true;
208}
209
210bool AVRMCExpr::evaluateAsConstant(int64_t &Result) const {
212 bool isRelocatable = getSubExpr()->evaluateAsRelocatable(Value, nullptr);
213 if (!isRelocatable)
214 return false;
215
216 if (Value.isAbsolute()) {
217 Result = evaluateAsInt64(Value.getConstant());
218 return true;
219 }
220
221 return false;
222}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
std::string Name
static LVOptions Options
Definition: LVOptions.cpp:25
raw_pwrite_stream & OS
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.
void printExpr(raw_ostream &, const MCExpr &) const
Definition: MCAsmInfo.cpp:153
bool UsesELFSectionDirectiveForBSS
This is true if this target uses ELF '.section' directive before the '.bss' one.
Definition: MCAsmInfo.h:263
bool SupportsDebugInformation
True if target supports emission of debugging information.
Definition: MCAsmInfo.h:356
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.
@ S_LO8
Corresponds to lo8().
Definition: AVRMCAsmInfo.h:42
@ S_LO8_GS
Corresponds to lo8(gs()).
Definition: AVRMCAsmInfo.h:51
@ S_HH8
Corresponds to hlo8() and hh8().
Definition: AVRMCAsmInfo.h:43
@ S_PM_HH8
Corresponds to pm_hh8().
Definition: AVRMCAsmInfo.h:49
@ S_HHI8
Corresponds to hhi8().
Definition: AVRMCAsmInfo.h:44
@ S_PM_LO8
Corresponds to pm_lo8().
Definition: AVRMCAsmInfo.h:47
@ S_PM
Corresponds to pm(), reference to program memory.
Definition: AVRMCAsmInfo.h:46
@ S_GS
Corresponds to gs().
Definition: AVRMCAsmInfo.h:53
@ S_HI8_GS
Corresponds to hi8(gs()).
Definition: AVRMCAsmInfo.h:52
@ S_PM_HI8
Corresponds to pm_hi8().
Definition: AVRMCAsmInfo.h:48
@ S_HI8
Corresponds to hi8().
Definition: AVRMCAsmInfo.h:41
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:1777