Skip to content

Commit 47e76c1

Browse files
committed
[AVR] Handle mapped RO data for newer devices
1 parent ee414e3 commit 47e76c1

File tree

5 files changed

+67
-28
lines changed

5 files changed

+67
-28
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4886,6 +4886,10 @@ def mguard_EQ : Joined<["-"], "mguard=">, Group<m_Group>,
48864886
HelpText<"Enable or disable Control Flow Guard checks and guard tables emission">,
48874887
Values<"none,cf,cf-nochecks">;
48884888
def mmcu_EQ : Joined<["-"], "mmcu=">, Group<m_Group>;
4889+
def mflmap : Flag<["-"], "mflmap">, Group<m_Group>,
4890+
HelpText<"Use AVR mapped memory for RO data">;
4891+
def mrodata_in_ram : Flag<["-"], "mrodata-in-ram">, Group<m_Group>,
4892+
HelpText<"Copy RO data to ram">;
48894893
def msim : Flag<["-"], "msim">, Group<m_Group>;
48904894
def mfix_and_continue : Flag<["-"], "mfix-and-continue">, Group<clang_ignored_m_Group>;
48914895
def mieee_fp : Flag<["-"], "mieee-fp">, Group<clang_ignored_m_Group>;

clang/lib/Basic/Targets/AVR.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,10 @@ static MCUInfo AVRMcus[] = {
418418
} // namespace targets
419419
} // namespace clang
420420

421+
static bool ArchHasFLMAP(StringRef Name) {
422+
return Name.starts_with("avr64") or Name.starts_with("avr128");
423+
}
424+
421425
static bool ArchHasELPM(StringRef Arch) {
422426
return llvm::StringSwitch<bool>(Arch)
423427
.Cases("31", "51", "6", true)
@@ -529,6 +533,8 @@ void AVRTargetInfo::getTargetDefines(const LangOptions &Opts,
529533
Builder.defineMacro("__AVR_ARCH__", Arch);
530534

531535
// TODO: perhaps we should use the information from AVRDevices.td instead?
536+
if (ArchHasFLMAP(DefineName))
537+
Builder.defineMacro("__AVR_HAVE_FLMAP__");
532538
if (ArchHasELPM(Arch))
533539
Builder.defineMacro("__AVR_HAVE_ELPM__");
534540
if (ArchHasELPMX(Arch))

clang/lib/Driver/ToolChains/AVR.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -651,8 +651,19 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA,
651651
// This is almost always required because otherwise avr-ld
652652
// will assume 'avr2' and warn about the program being larger
653653
// than the bare minimum supports.
654-
if (Linker.find("avr-ld") != std::string::npos && FamilyName)
655-
CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName));
654+
if (Linker.find("avr-ld") != std::string::npos && FamilyName) {
655+
// Option to use mapped memory for modern devices with >32kB flash.
656+
// This is the only option for modern devices with <= 32kB flash,
657+
// but the larger default to a copy from flash to RAM (avr-ld version < 14)
658+
// or map the highest 32kB to RAM (avr-ld version >= 14).
659+
if (Args.hasFlag(options::OPT_mflmap, options::OPT_mrodata_in_ram, false)) {
660+
CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName + "_flmap"));
661+
CmdArgs.push_back(Args.MakeArgString(std::string("-u")));
662+
CmdArgs.push_back(Args.MakeArgString(std::string("__do_flmap_init")));
663+
}
664+
else
665+
CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName));
666+
}
656667

657668
C.addCommand(std::make_unique<Command>(
658669
JA, *this, ResponseFileSupport::AtFileCurCP(), Args.MakeArgString(Linker),

llvm/lib/Target/AVR/AVRAsmPrinter.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,11 +263,17 @@ bool AVRAsmPrinter::doFinalization(Module &M) {
263263
auto *Section = cast<MCSectionELF>(TLOF.SectionForGlobal(&GO, TM));
264264
if (Section->getName().starts_with(".data"))
265265
NeedsCopyData = true;
266-
else if (Section->getName().starts_with(".rodata") && SubTM->hasLPM())
266+
else if (Section->getName().starts_with(".rodata") && SubTM->hasLPM()) {
267267
// AVRs that have a separate program memory (that's most AVRs) store
268-
// .rodata sections in RAM.
269-
NeedsCopyData = true;
270-
else if (Section->getName().starts_with(".bss"))
268+
// .rodata sections in RAM,
269+
// but XMEGA3 family maps all flash in the data space.
270+
// Invoking __do_copy_data with 0 bytes to copy will crash,
271+
// so we let the loader handle this for newer devices.
272+
if (!(SubTM->hasFeatureSetFamilyXMEGA2() ||
273+
SubTM->hasFeatureSetFamilyXMEGA3() ||
274+
SubTM->hasFeatureSetFamilyXMEGA4()))
275+
NeedsCopyData = true;
276+
} else if (Section->getName().starts_with(".bss"))
271277
NeedsClearBSS = true;
272278
}
273279

llvm/lib/Target/AVR/AVRDevices.td

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ def FeatureEIJMPCALL : SubtargetFeature<"eijmpcall", "HasEIJMPCALL", "true",
4949
"The device supports the "
5050
"`EIJMP`/`EICALL` instructions">;
5151

52+
// The device supports `FLMAP` flash bank data mapping to the data space.
53+
def FeatureFLMAP : SubtargetFeature<"flmap", "HasFLMAP", "true",
54+
"The device supports the "
55+
"`FLMAP` mapping">;
56+
57+
// The device maps all flash (<= 32kB) to the data space.
58+
def FeatureMAP : SubtargetFeature<"map", "HasMAP", "true",
59+
"The device maps all flash (<= 32kB) "
60+
"to the data space">;
61+
5262
// The device supports `ADDI Rd, K`, `SUBI Rd, K`.
5363
def FeatureADDSUBIW : SubtargetFeature<"addsubiw", "HasADDSUBIW", "true",
5464
"Enable 16-bit register-immediate "
@@ -220,6 +230,7 @@ def FamilyXMEGA3 : Family<"xmega3",
220230
[FamilyAVR0, FeatureLPM, FeatureIJMPCALL,
221231
FeatureADDSUBIW, FeatureSRAM, FeatureJMPCALL,
222232
FeatureMultiplication, FeatureMOVW, FeatureLPMX,
233+
FeatureMAP,
223234
FeatureBREAK, FeatureLowByteFirst]>;
224235

225236
def FamilyXMEGA4 : Family<"xmega4",
@@ -228,6 +239,7 @@ def FamilyXMEGA4 : Family<"xmega4",
228239
FeatureMultiplication, FeatureMOVW, FeatureLPMX,
229240
FeatureELPM, FeatureELPMX,
230241
FeatureSPM, FeatureSPMX,
242+
FeatureFLMAP,
231243
FeatureBREAK, FeatureLowByteFirst]>;
232244

233245
def FamilyXMEGA : Family<"xmega",
@@ -275,9 +287,9 @@ def : Device<"avr5", FamilyAVR5, ELFArchAVR5>;
275287
def : Device<"avr51", FamilyAVR51, ELFArchAVR51>;
276288
def : Device<"avr6", FamilyAVR6, ELFArchAVR6>;
277289
def : Device<"avrxmega1", FamilyXMEGA, ELFArchXMEGA1>;
278-
def : Device<"avrxmega2", FamilyXMEGA, ELFArchXMEGA2>;
290+
def : Device<"avrxmega2", FamilyXMEGA2, ELFArchXMEGA2>;
279291
def : Device<"avrxmega3", FamilyXMEGA3, ELFArchXMEGA3>;
280-
def : Device<"avrxmega4", FamilyXMEGA, ELFArchXMEGA4>;
292+
def : Device<"avrxmega4", FamilyXMEGA4, ELFArchXMEGA4>;
281293
def : Device<"avrxmega5", FamilyXMEGA, ELFArchXMEGA5>;
282294
def : Device<"avrxmega6", FamilyXMEGA, ELFArchXMEGA6>;
283295
def : Device<"avrxmega7", FamilyXMEGA, ELFArchXMEGA7>;
@@ -596,26 +608,26 @@ def : Device<"atmega4809", FamilyXMEGA3, ELFArchXMEGA3>;
596608

597609
// Additions from gcc 14:
598610

599-
def : Device<"avr64da28", FamilyXMEGA2, ELFArchXMEGA2>;
600-
def : Device<"avr64da32", FamilyXMEGA2, ELFArchXMEGA2>;
601-
def : Device<"avr64da48", FamilyXMEGA2, ELFArchXMEGA2>;
602-
def : Device<"avr64da64", FamilyXMEGA2, ELFArchXMEGA2>;
603-
def : Device<"avr64db28", FamilyXMEGA2, ELFArchXMEGA2>;
604-
def : Device<"avr64db32", FamilyXMEGA2, ELFArchXMEGA2>;
605-
def : Device<"avr64db48", FamilyXMEGA2, ELFArchXMEGA2>;
606-
def : Device<"avr64db64", FamilyXMEGA2, ELFArchXMEGA2>;
607-
def : Device<"avr64dd14", FamilyXMEGA2, ELFArchXMEGA2>;
608-
def : Device<"avr64dd20", FamilyXMEGA2, ELFArchXMEGA2>;
609-
def : Device<"avr64dd28", FamilyXMEGA2, ELFArchXMEGA2>;
610-
def : Device<"avr64dd32", FamilyXMEGA2, ELFArchXMEGA2>;
611-
def : Device<"avr64du28", FamilyXMEGA2, ELFArchXMEGA2>;
612-
def : Device<"avr64du32", FamilyXMEGA2, ELFArchXMEGA2>;
613-
def : Device<"avr64ea28", FamilyXMEGA2, ELFArchXMEGA2>;
614-
def : Device<"avr64ea32", FamilyXMEGA2, ELFArchXMEGA2>;
615-
def : Device<"avr64ea48", FamilyXMEGA2, ELFArchXMEGA2>;
616-
def : Device<"avr64sd28", FamilyXMEGA2, ELFArchXMEGA2>;
617-
def : Device<"avr64sd32", FamilyXMEGA2, ELFArchXMEGA2>;
618-
def : Device<"avr64sd48", FamilyXMEGA2, ELFArchXMEGA2>;
611+
def : Device<"avr64da28", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
612+
def : Device<"avr64da32", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
613+
def : Device<"avr64da48", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
614+
def : Device<"avr64da64", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
615+
def : Device<"avr64db28", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
616+
def : Device<"avr64db32", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
617+
def : Device<"avr64db48", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
618+
def : Device<"avr64db64", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
619+
def : Device<"avr64dd14", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
620+
def : Device<"avr64dd20", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
621+
def : Device<"avr64dd28", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
622+
def : Device<"avr64dd32", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
623+
def : Device<"avr64du28", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
624+
def : Device<"avr64du32", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
625+
def : Device<"avr64ea28", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
626+
def : Device<"avr64ea32", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
627+
def : Device<"avr64ea48", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
628+
def : Device<"avr64sd28", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
629+
def : Device<"avr64sd32", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
630+
def : Device<"avr64sd48", FamilyXMEGA2, ELFArchXMEGA2, [FeatureFLMAP]>;
619631

620632
def : Device<"avr16dd20", FamilyXMEGA3, ELFArchXMEGA3>;
621633
def : Device<"avr16dd28", FamilyXMEGA3, ELFArchXMEGA3>;

0 commit comments

Comments
 (0)