1 //===-- AVRTargetObjectFile.cpp - AVR Object Files ------------------------===// 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 #include "AVRTargetObjectFile.h" 10 #include "AVRTargetMachine.h" 11 12 #include "llvm/BinaryFormat/ELF.h" 13 #include "llvm/IR/DerivedTypes.h" 14 #include "llvm/IR/GlobalValue.h" 15 #include "llvm/IR/Mangler.h" 16 #include "llvm/MC/MCContext.h" 17 #include "llvm/MC/MCSectionELF.h" 18 19 #include "AVR.h" 20 21 namespace llvm { 22 void AVRTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) { 23 Base::Initialize(Ctx, TM); 24 ProgmemDataSection = 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); 36 } 37 38 MCSection *AVRTargetObjectFile::SelectSectionForGlobal( 39 const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { 40 // Global values in flash memory are placed in the progmem*.data section 41 // unless they already have a user assigned section. 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 } 80 81 // Otherwise, we work the same way as ELF. 82 return Base::SelectSectionForGlobal(GO, Kind, TM); 83 } 84 } // end of namespace llvm 85