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