77// ===----------------------------------------------------------------------===//
88
99#include " AVRTargetObjectFile.h"
10+ #include " AVRTargetMachine.h"
1011
1112#include " llvm/BinaryFormat/ELF.h"
1213#include " llvm/IR/DerivedTypes.h"
@@ -22,14 +23,60 @@ void AVRTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) {
2223 Base::Initialize (Ctx, TM);
2324 ProgmemDataSection =
2425 Ctx.getELFSection (" .progmem.data" , ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
26+ Progmem1DataSection =
27+ Ctx.getELFSection (" .progmem1.data" , ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
28+ Progmem2DataSection =
29+ Ctx.getELFSection (" .progmem2.data" , ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
30+ Progmem3DataSection =
31+ Ctx.getELFSection (" .progmem3.data" , ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
32+ Progmem4DataSection =
33+ Ctx.getELFSection (" .progmem4.data" , ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
34+ Progmem5DataSection =
35+ Ctx.getELFSection (" .progmem5.data" , ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
2536}
2637
2738MCSection *AVRTargetObjectFile::SelectSectionForGlobal (
2839 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
29- // Global values in flash memory are placed in the progmem.data section
40+ // Global values in flash memory are placed in the progmem* .data section
3041 // unless they already have a user assigned section.
31- if (AVR::isProgramMemoryAddress (GO) && !GO->hasSection () && Kind.isReadOnly ())
32- return ProgmemDataSection;
42+ const auto &AVRTM = static_cast <const AVRTargetMachine &>(TM);
43+ if (AVR::isProgramMemoryAddress (GO) && !GO->hasSection () &&
44+ Kind.isReadOnly ()) {
45+ // The AVR subtarget should support LPM to access section '.progmem*.data'.
46+ if (!AVRTM.getSubtargetImpl ()->hasLPM ()) {
47+ // TODO: Get the global object's location in source file.
48+ getContext ().reportError (
49+ SMLoc (),
50+ " Current AVR subtarget does not support accessing program memory" );
51+ return Base::SelectSectionForGlobal (GO, Kind, TM);
52+ }
53+ // The AVR subtarget should support ELPM to access section
54+ // '.progmem[1|2|3|4|5].data'.
55+ if (!AVRTM.getSubtargetImpl ()->hasELPM () &&
56+ AVR::getAddressSpace (GO) != AVR::ProgramMemory) {
57+ // TODO: Get the global object's location in source file.
58+ getContext ().reportError (SMLoc (),
59+ " Current AVR subtarget does not support "
60+ " accessing extended program memory" );
61+ return ProgmemDataSection;
62+ }
63+ switch (AVR::getAddressSpace (GO)) {
64+ case AVR::ProgramMemory: // address space 1
65+ return ProgmemDataSection;
66+ case AVR::ProgramMemory1: // address space 2
67+ return Progmem1DataSection;
68+ case AVR::ProgramMemory2: // address space 3
69+ return Progmem2DataSection;
70+ case AVR::ProgramMemory3: // address space 4
71+ return Progmem3DataSection;
72+ case AVR::ProgramMemory4: // address space 5
73+ return Progmem4DataSection;
74+ case AVR::ProgramMemory5: // address space 6
75+ return Progmem5DataSection;
76+ default :
77+ llvm_unreachable (" unexpected program memory index" );
78+ }
79+ }
3380
3481 // Otherwise, we work the same way as ELF.
3582 return Base::SelectSectionForGlobal (GO, Kind, TM);
0 commit comments