1111// ===----------------------------------------------------------------------===//
1212
1313#include " AVRMCAsmInfo.h"
14+ #include " llvm/MC/MCAssembler.h"
15+ #include " llvm/MC/MCContext.h"
1416#include " llvm/MC/MCExpr.h"
17+ #include " llvm/MC/MCValue.h"
1518#include " llvm/TargetParser/Triple.h"
1619
1720using namespace llvm ;
@@ -26,3 +29,179 @@ AVRMCAsmInfo::AVRMCAsmInfo(const Triple &TT, const MCTargetOptions &Options) {
2629 UsesELFSectionDirectiveForBSS = true ;
2730 SupportsDebugInformation = true ;
2831}
32+
33+ namespace {
34+ const struct ModifierEntry {
35+ const char *const Spelling;
36+ AVRMCExpr::Specifier specifier;
37+ } ModifierNames[] = {
38+ {" lo8" , AVR::S_LO8}, {" hi8" , AVR::S_HI8},
39+ {" hh8" , AVR::S_HH8}, // synonym with hlo8
40+ {" hlo8" , AVR::S_HH8}, {" hhi8" , AVR::S_HHI8},
41+
42+ {" pm" , AVR::S_PM}, {" pm_lo8" , AVR::S_PM_LO8},
43+ {" pm_hi8" , AVR::S_PM_HI8}, {" pm_hh8" , AVR::S_PM_HH8},
44+
45+ {" lo8_gs" , AVR::S_LO8_GS}, {" hi8_gs" , AVR::S_HI8_GS},
46+ {" gs" , AVR::S_GS},
47+ };
48+
49+ } // end of anonymous namespace
50+
51+ AVRMCExpr::Specifier AVRMCExpr::parseSpecifier (StringRef Name) {
52+ const auto &Modifier =
53+ llvm::find_if (ModifierNames, [&Name](ModifierEntry const &Mod) {
54+ return Mod.Spelling == Name;
55+ });
56+
57+ if (Modifier != std::end (ModifierNames)) {
58+ return Modifier->specifier ;
59+ }
60+ return AVR::S_AVR_NONE;
61+ }
62+
63+ const char *AVRMCExpr::getName () const {
64+ const auto &Modifier =
65+ llvm::find_if (ModifierNames, [this ](ModifierEntry const &Mod) {
66+ return Mod.specifier == specifier;
67+ });
68+
69+ if (Modifier != std::end (ModifierNames)) {
70+ return Modifier->Spelling ;
71+ }
72+ return nullptr ;
73+ }
74+
75+ AVR::Fixups AVRMCExpr::getFixupKind () const {
76+ AVR::Fixups Kind = AVR::Fixups::LastTargetFixupKind;
77+
78+ switch (specifier) {
79+ case AVR::S_LO8:
80+ Kind = isNegated () ? AVR::fixup_lo8_ldi_neg : AVR::fixup_lo8_ldi;
81+ break ;
82+ case AVR::S_HI8:
83+ Kind = isNegated () ? AVR::fixup_hi8_ldi_neg : AVR::fixup_hi8_ldi;
84+ break ;
85+ case AVR::S_HH8:
86+ Kind = isNegated () ? AVR::fixup_hh8_ldi_neg : AVR::fixup_hh8_ldi;
87+ break ;
88+ case AVR::S_HHI8:
89+ Kind = isNegated () ? AVR::fixup_ms8_ldi_neg : AVR::fixup_ms8_ldi;
90+ break ;
91+
92+ case AVR::S_PM_LO8:
93+ Kind = isNegated () ? AVR::fixup_lo8_ldi_pm_neg : AVR::fixup_lo8_ldi_pm;
94+ break ;
95+ case AVR::S_PM_HI8:
96+ Kind = isNegated () ? AVR::fixup_hi8_ldi_pm_neg : AVR::fixup_hi8_ldi_pm;
97+ break ;
98+ case AVR::S_PM_HH8:
99+ Kind = isNegated () ? AVR::fixup_hh8_ldi_pm_neg : AVR::fixup_hh8_ldi_pm;
100+ break ;
101+ case AVR::S_PM:
102+ case AVR::S_GS:
103+ Kind = AVR::fixup_16_pm;
104+ break ;
105+ case AVR::S_LO8_GS:
106+ Kind = AVR::fixup_lo8_ldi_gs;
107+ break ;
108+ case AVR::S_HI8_GS:
109+ Kind = AVR::fixup_hi8_ldi_gs;
110+ break ;
111+
112+ default :
113+ llvm_unreachable (" Uninitialized expression" );
114+ }
115+
116+ return Kind;
117+ }
118+
119+ int64_t AVRMCExpr::evaluateAsInt64 (int64_t Value) const {
120+ if (Negated)
121+ Value *= -1 ;
122+
123+ switch (specifier) {
124+ case AVR::S_LO8:
125+ Value &= 0xff ;
126+ break ;
127+ case AVR::S_HI8:
128+ Value &= 0xff00 ;
129+ Value >>= 8 ;
130+ break ;
131+ case AVR::S_HH8:
132+ Value &= 0xff0000 ;
133+ Value >>= 16 ;
134+ break ;
135+ case AVR::S_HHI8:
136+ Value &= 0xff000000 ;
137+ Value >>= 24 ;
138+ break ;
139+ case AVR::S_PM_LO8:
140+ case AVR::S_LO8_GS:
141+ Value >>= 1 ; // Program memory addresses must always be shifted by one.
142+ Value &= 0xff ;
143+ break ;
144+ case AVR::S_PM_HI8:
145+ case AVR::S_HI8_GS:
146+ Value >>= 1 ; // Program memory addresses must always be shifted by one.
147+ Value &= 0xff00 ;
148+ Value >>= 8 ;
149+ break ;
150+ case AVR::S_PM_HH8:
151+ Value >>= 1 ; // Program memory addresses must always be shifted by one.
152+ Value &= 0xff0000 ;
153+ Value >>= 16 ;
154+ break ;
155+ case AVR::S_PM:
156+ case AVR::S_GS:
157+ Value >>= 1 ; // Program memory addresses must always be shifted by one.
158+ break ;
159+
160+ case AVR::S_AVR_NONE:
161+ default :
162+ llvm_unreachable (" Uninitialized expression." );
163+ }
164+ return static_cast <uint64_t >(Value) & 0xff ;
165+ }
166+
167+ bool AVRMCExpr::evaluateAsRelocatableImpl (MCValue &Result,
168+ const MCAssembler *Asm) const {
169+ MCValue Value;
170+ bool isRelocatable = getSubExpr ()->evaluateAsRelocatable (Value, Asm);
171+ if (!isRelocatable)
172+ return false ;
173+
174+ if (Value.isAbsolute ()) {
175+ Result = MCValue::get (evaluateAsInt64 (Value.getConstant ()));
176+ } else {
177+ if (!Asm || !Asm->hasLayout ())
178+ return false ;
179+
180+ auto Spec = AVR::S_None;
181+ if (Value.getSpecifier () != MCSymbolRefExpr::VK_None)
182+ return false ;
183+ assert (!Value.getSubSym ());
184+ if (specifier == AVR::S_PM)
185+ Spec = AVR::S_PM;
186+
187+ // TODO: don't attach specifier to MCSymbolRefExpr.
188+ Result =
189+ MCValue::get (Value.getAddSym (), nullptr , Value.getConstant (), Spec);
190+ }
191+
192+ return true ;
193+ }
194+
195+ bool AVRMCExpr::evaluateAsConstant (int64_t &Result) const {
196+ MCValue Value;
197+ bool isRelocatable = getSubExpr ()->evaluateAsRelocatable (Value, nullptr );
198+ if (!isRelocatable)
199+ return false ;
200+
201+ if (Value.isAbsolute ()) {
202+ Result = evaluateAsInt64 (Value.getConstant ());
203+ return true ;
204+ }
205+
206+ return false ;
207+ }
0 commit comments