xref: /src/contrib/llvm-project/llvm/lib/Target/AVR/AVRTargetObjectFile.cpp (revision 04eeddc0aa8e0a417a16eaf9d7d095207f4a8623)
1050e163aSDimitry Andric //===-- AVRTargetObjectFile.cpp - AVR Object Files ------------------------===//
2050e163aSDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6050e163aSDimitry Andric //
7050e163aSDimitry Andric //===----------------------------------------------------------------------===//
8050e163aSDimitry Andric 
9050e163aSDimitry Andric #include "AVRTargetObjectFile.h"
106f8fc217SDimitry Andric #include "AVRTargetMachine.h"
11050e163aSDimitry Andric 
127ab83427SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
13050e163aSDimitry Andric #include "llvm/IR/DerivedTypes.h"
14050e163aSDimitry Andric #include "llvm/IR/GlobalValue.h"
15050e163aSDimitry Andric #include "llvm/IR/Mangler.h"
16050e163aSDimitry Andric #include "llvm/MC/MCContext.h"
17050e163aSDimitry Andric #include "llvm/MC/MCSectionELF.h"
18050e163aSDimitry Andric 
19050e163aSDimitry Andric #include "AVR.h"
20050e163aSDimitry Andric 
21050e163aSDimitry Andric namespace llvm {
Initialize(MCContext & Ctx,const TargetMachine & TM)22050e163aSDimitry Andric void AVRTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) {
23050e163aSDimitry Andric   Base::Initialize(Ctx, TM);
24050e163aSDimitry Andric   ProgmemDataSection =
25050e163aSDimitry Andric       Ctx.getELFSection(".progmem.data", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
266f8fc217SDimitry Andric   Progmem1DataSection =
276f8fc217SDimitry Andric       Ctx.getELFSection(".progmem1.data", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
286f8fc217SDimitry Andric   Progmem2DataSection =
296f8fc217SDimitry Andric       Ctx.getELFSection(".progmem2.data", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
306f8fc217SDimitry Andric   Progmem3DataSection =
316f8fc217SDimitry Andric       Ctx.getELFSection(".progmem3.data", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
326f8fc217SDimitry Andric   Progmem4DataSection =
336f8fc217SDimitry Andric       Ctx.getELFSection(".progmem4.data", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
346f8fc217SDimitry Andric   Progmem5DataSection =
356f8fc217SDimitry Andric       Ctx.getELFSection(".progmem5.data", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
36050e163aSDimitry Andric }
37050e163aSDimitry Andric 
SelectSectionForGlobal(const GlobalObject * GO,SectionKind Kind,const TargetMachine & TM) const38c0981da4SDimitry Andric MCSection *AVRTargetObjectFile::SelectSectionForGlobal(
39c0981da4SDimitry Andric     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
406f8fc217SDimitry Andric   // Global values in flash memory are placed in the progmem*.data section
41050e163aSDimitry Andric   // unless they already have a user assigned section.
426f8fc217SDimitry Andric   const auto &AVRTM = static_cast<const AVRTargetMachine &>(TM);
436f8fc217SDimitry Andric   if (AVR::isProgramMemoryAddress(GO) && !GO->hasSection() &&
446f8fc217SDimitry Andric       Kind.isReadOnly()) {
456f8fc217SDimitry Andric     // The AVR subtarget should support LPM to access section '.progmem*.data'.
466f8fc217SDimitry Andric     if (!AVRTM.getSubtargetImpl()->hasLPM()) {
476f8fc217SDimitry Andric       // TODO: Get the global object's location in source file.
486f8fc217SDimitry Andric       getContext().reportError(
496f8fc217SDimitry Andric           SMLoc(),
506f8fc217SDimitry Andric           "Current AVR subtarget does not support accessing program memory");
516f8fc217SDimitry Andric       return Base::SelectSectionForGlobal(GO, Kind, TM);
526f8fc217SDimitry Andric     }
536f8fc217SDimitry Andric     // The AVR subtarget should support ELPM to access section
546f8fc217SDimitry Andric     // '.progmem[1|2|3|4|5].data'.
556f8fc217SDimitry Andric     if (!AVRTM.getSubtargetImpl()->hasELPM() &&
566f8fc217SDimitry Andric         AVR::getAddressSpace(GO) != AVR::ProgramMemory) {
576f8fc217SDimitry Andric       // TODO: Get the global object's location in source file.
586f8fc217SDimitry Andric       getContext().reportError(SMLoc(),
596f8fc217SDimitry Andric                                "Current AVR subtarget does not support "
606f8fc217SDimitry Andric                                "accessing extended program memory");
61050e163aSDimitry Andric       return ProgmemDataSection;
626f8fc217SDimitry Andric     }
636f8fc217SDimitry Andric     switch (AVR::getAddressSpace(GO)) {
646f8fc217SDimitry Andric     case AVR::ProgramMemory: // address space 1
656f8fc217SDimitry Andric       return ProgmemDataSection;
666f8fc217SDimitry Andric     case AVR::ProgramMemory1: // address space 2
676f8fc217SDimitry Andric       return Progmem1DataSection;
686f8fc217SDimitry Andric     case AVR::ProgramMemory2: // address space 3
696f8fc217SDimitry Andric       return Progmem2DataSection;
706f8fc217SDimitry Andric     case AVR::ProgramMemory3: // address space 4
716f8fc217SDimitry Andric       return Progmem3DataSection;
726f8fc217SDimitry Andric     case AVR::ProgramMemory4: // address space 5
736f8fc217SDimitry Andric       return Progmem4DataSection;
746f8fc217SDimitry Andric     case AVR::ProgramMemory5: // address space 6
756f8fc217SDimitry Andric       return Progmem5DataSection;
766f8fc217SDimitry Andric     default:
776f8fc217SDimitry Andric       llvm_unreachable("unexpected program memory index");
786f8fc217SDimitry Andric     }
796f8fc217SDimitry Andric   }
80050e163aSDimitry Andric 
81050e163aSDimitry Andric   // Otherwise, we work the same way as ELF.
82b915e9e0SDimitry Andric   return Base::SelectSectionForGlobal(GO, Kind, TM);
83050e163aSDimitry Andric }
84050e163aSDimitry Andric } // end of namespace llvm
85