7
7
// ===----------------------------------------------------------------------===//
8
8
9
9
#include " AVRTargetObjectFile.h"
10
+ #include " AVRTargetMachine.h"
10
11
11
12
#include " llvm/BinaryFormat/ELF.h"
12
13
#include " llvm/IR/DerivedTypes.h"
@@ -22,14 +23,60 @@ void AVRTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) {
22
23
Base::Initialize (Ctx, TM);
23
24
ProgmemDataSection =
24
25
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);
25
36
}
26
37
27
38
MCSection *AVRTargetObjectFile::SelectSectionForGlobal (
28
39
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
30
41
// 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
+ }
33
80
34
81
// Otherwise, we work the same way as ELF.
35
82
return Base::SelectSectionForGlobal (GO, Kind, TM);
0 commit comments