14a25499bSDylan McKay //===-- AVRELFObjectWriter.cpp - AVR ELF Writer ---------------------------===//
24a25499bSDylan McKay //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64a25499bSDylan McKay //
74a25499bSDylan McKay //===----------------------------------------------------------------------===//
84a25499bSDylan McKay
94a25499bSDylan McKay #include "MCTargetDesc/AVRFixupKinds.h"
102ccb9417SDylan McKay #include "MCTargetDesc/AVRMCExpr.h"
114a25499bSDylan McKay #include "MCTargetDesc/AVRMCTargetDesc.h"
124a25499bSDylan McKay
134a25499bSDylan McKay #include "llvm/MC/MCAssembler.h"
144a25499bSDylan McKay #include "llvm/MC/MCELFObjectWriter.h"
154a25499bSDylan McKay #include "llvm/MC/MCExpr.h"
16bebde41eSDylan McKay #include "llvm/MC/MCObjectWriter.h"
174a25499bSDylan McKay #include "llvm/MC/MCSection.h"
184a25499bSDylan McKay #include "llvm/MC/MCValue.h"
194a25499bSDylan McKay #include "llvm/Support/ErrorHandling.h"
204a25499bSDylan McKay
214a25499bSDylan McKay namespace llvm {
224a25499bSDylan McKay
234a25499bSDylan McKay /// Writes AVR machine code into an ELF32 object file.
244a25499bSDylan McKay class AVRELFObjectWriter : public MCELFObjectTargetWriter {
254a25499bSDylan McKay public:
264a25499bSDylan McKay AVRELFObjectWriter(uint8_t OSABI);
274a25499bSDylan McKay
28*3a3cb929SKazu Hirata virtual ~AVRELFObjectWriter() = default;
294a25499bSDylan McKay
305449d2daSShivam Gupta unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
315449d2daSShivam Gupta const MCFixup &Fixup, bool IsPCRel) const override;
324a25499bSDylan McKay };
334a25499bSDylan McKay
AVRELFObjectWriter(uint8_t OSABI)344a25499bSDylan McKay AVRELFObjectWriter::AVRELFObjectWriter(uint8_t OSABI)
35b7926ba5SDylan McKay : MCELFObjectTargetWriter(false, OSABI, ELF::EM_AVR, true) {}
364a25499bSDylan McKay
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const375449d2daSShivam Gupta unsigned AVRELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
384a25499bSDylan McKay const MCFixup &Fixup,
394a25499bSDylan McKay bool IsPCRel) const {
40ba23343aSDylan McKay MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
414a25499bSDylan McKay switch ((unsigned)Fixup.getKind()) {
424a25499bSDylan McKay case FK_Data_1:
43ba23343aSDylan McKay switch (Modifier) {
44ba23343aSDylan McKay default:
45ba23343aSDylan McKay llvm_unreachable("Unsupported Modifier");
46ba23343aSDylan McKay case MCSymbolRefExpr::VK_None:
47ba23343aSDylan McKay return ELF::R_AVR_8;
48ba23343aSDylan McKay case MCSymbolRefExpr::VK_AVR_DIFF8:
49ba23343aSDylan McKay return ELF::R_AVR_DIFF8;
50ba23343aSDylan McKay case MCSymbolRefExpr::VK_AVR_LO8:
51ba23343aSDylan McKay return ELF::R_AVR_8_LO8;
52ba23343aSDylan McKay case MCSymbolRefExpr::VK_AVR_HI8:
53ba23343aSDylan McKay return ELF::R_AVR_8_HI8;
54ba23343aSDylan McKay case MCSymbolRefExpr::VK_AVR_HLO8:
55ba23343aSDylan McKay return ELF::R_AVR_8_HLO8;
56ba23343aSDylan McKay }
574a25499bSDylan McKay case FK_Data_4:
58ba23343aSDylan McKay switch (Modifier) {
59ba23343aSDylan McKay default:
60ba23343aSDylan McKay llvm_unreachable("Unsupported Modifier");
61ba23343aSDylan McKay case MCSymbolRefExpr::VK_None:
62ba23343aSDylan McKay return ELF::R_AVR_32;
63ba23343aSDylan McKay case MCSymbolRefExpr::VK_AVR_DIFF32:
64ba23343aSDylan McKay return ELF::R_AVR_DIFF32;
65ba23343aSDylan McKay }
664a25499bSDylan McKay case FK_Data_2:
67ba23343aSDylan McKay switch (Modifier) {
68ba23343aSDylan McKay default:
69ba23343aSDylan McKay llvm_unreachable("Unsupported Modifier");
70ba23343aSDylan McKay case MCSymbolRefExpr::VK_None:
71ba23343aSDylan McKay return ELF::R_AVR_16;
72ba23343aSDylan McKay case MCSymbolRefExpr::VK_AVR_NONE:
732ccb9417SDylan McKay case MCSymbolRefExpr::VK_AVR_PM:
744a25499bSDylan McKay return ELF::R_AVR_16_PM;
75ba23343aSDylan McKay case MCSymbolRefExpr::VK_AVR_DIFF16:
76ba23343aSDylan McKay return ELF::R_AVR_DIFF16;
77ba23343aSDylan McKay }
784a25499bSDylan McKay case AVR::fixup_32:
794a25499bSDylan McKay return ELF::R_AVR_32;
804a25499bSDylan McKay case AVR::fixup_7_pcrel:
814a25499bSDylan McKay return ELF::R_AVR_7_PCREL;
824a25499bSDylan McKay case AVR::fixup_13_pcrel:
834a25499bSDylan McKay return ELF::R_AVR_13_PCREL;
844a25499bSDylan McKay case AVR::fixup_16:
854a25499bSDylan McKay return ELF::R_AVR_16;
864a25499bSDylan McKay case AVR::fixup_16_pm:
874a25499bSDylan McKay return ELF::R_AVR_16_PM;
884a25499bSDylan McKay case AVR::fixup_lo8_ldi:
894a25499bSDylan McKay return ELF::R_AVR_LO8_LDI;
904a25499bSDylan McKay case AVR::fixup_hi8_ldi:
914a25499bSDylan McKay return ELF::R_AVR_HI8_LDI;
924a25499bSDylan McKay case AVR::fixup_hh8_ldi:
934a25499bSDylan McKay return ELF::R_AVR_HH8_LDI;
944a25499bSDylan McKay case AVR::fixup_lo8_ldi_neg:
954a25499bSDylan McKay return ELF::R_AVR_LO8_LDI_NEG;
964a25499bSDylan McKay case AVR::fixup_hi8_ldi_neg:
974a25499bSDylan McKay return ELF::R_AVR_HI8_LDI_NEG;
984a25499bSDylan McKay case AVR::fixup_hh8_ldi_neg:
994a25499bSDylan McKay return ELF::R_AVR_HH8_LDI_NEG;
1004a25499bSDylan McKay case AVR::fixup_lo8_ldi_pm:
1014a25499bSDylan McKay return ELF::R_AVR_LO8_LDI_PM;
1024a25499bSDylan McKay case AVR::fixup_hi8_ldi_pm:
1034a25499bSDylan McKay return ELF::R_AVR_HI8_LDI_PM;
1044a25499bSDylan McKay case AVR::fixup_hh8_ldi_pm:
1054a25499bSDylan McKay return ELF::R_AVR_HH8_LDI_PM;
1064a25499bSDylan McKay case AVR::fixup_lo8_ldi_pm_neg:
1074a25499bSDylan McKay return ELF::R_AVR_LO8_LDI_PM_NEG;
1084a25499bSDylan McKay case AVR::fixup_hi8_ldi_pm_neg:
1094a25499bSDylan McKay return ELF::R_AVR_HI8_LDI_PM_NEG;
1104a25499bSDylan McKay case AVR::fixup_hh8_ldi_pm_neg:
1114a25499bSDylan McKay return ELF::R_AVR_HH8_LDI_PM_NEG;
1124a25499bSDylan McKay case AVR::fixup_call:
1134a25499bSDylan McKay return ELF::R_AVR_CALL;
1144a25499bSDylan McKay case AVR::fixup_ldi:
1154a25499bSDylan McKay return ELF::R_AVR_LDI;
1164a25499bSDylan McKay case AVR::fixup_6:
1174a25499bSDylan McKay return ELF::R_AVR_6;
1184a25499bSDylan McKay case AVR::fixup_6_adiw:
1194a25499bSDylan McKay return ELF::R_AVR_6_ADIW;
1204a25499bSDylan McKay case AVR::fixup_ms8_ldi:
1214a25499bSDylan McKay return ELF::R_AVR_MS8_LDI;
1224a25499bSDylan McKay case AVR::fixup_ms8_ldi_neg:
1234a25499bSDylan McKay return ELF::R_AVR_MS8_LDI_NEG;
1244a25499bSDylan McKay case AVR::fixup_lo8_ldi_gs:
1254a25499bSDylan McKay return ELF::R_AVR_LO8_LDI_GS;
1264a25499bSDylan McKay case AVR::fixup_hi8_ldi_gs:
1274a25499bSDylan McKay return ELF::R_AVR_HI8_LDI_GS;
1284a25499bSDylan McKay case AVR::fixup_8:
1294a25499bSDylan McKay return ELF::R_AVR_8;
1304a25499bSDylan McKay case AVR::fixup_8_lo8:
1314a25499bSDylan McKay return ELF::R_AVR_8_LO8;
1324a25499bSDylan McKay case AVR::fixup_8_hi8:
1334a25499bSDylan McKay return ELF::R_AVR_8_HI8;
1344a25499bSDylan McKay case AVR::fixup_8_hlo8:
1354a25499bSDylan McKay return ELF::R_AVR_8_HLO8;
136ba23343aSDylan McKay case AVR::fixup_diff8:
137ba23343aSDylan McKay return ELF::R_AVR_DIFF8;
138ba23343aSDylan McKay case AVR::fixup_diff16:
139ba23343aSDylan McKay return ELF::R_AVR_DIFF16;
140ba23343aSDylan McKay case AVR::fixup_diff32:
141ba23343aSDylan McKay return ELF::R_AVR_DIFF32;
1424a25499bSDylan McKay case AVR::fixup_lds_sts_16:
1434a25499bSDylan McKay return ELF::R_AVR_LDS_STS_16;
1444a25499bSDylan McKay case AVR::fixup_port6:
1454a25499bSDylan McKay return ELF::R_AVR_PORT6;
1464a25499bSDylan McKay case AVR::fixup_port5:
1474a25499bSDylan McKay return ELF::R_AVR_PORT5;
1484a25499bSDylan McKay default:
1494a25499bSDylan McKay llvm_unreachable("invalid fixup kind!");
1504a25499bSDylan McKay }
1514a25499bSDylan McKay }
1524a25499bSDylan McKay
createAVRELFObjectWriter(uint8_t OSABI)153dcd7d6c3SPeter Collingbourne std::unique_ptr<MCObjectTargetWriter> createAVRELFObjectWriter(uint8_t OSABI) {
1540eaee545SJonas Devlieghere return std::make_unique<AVRELFObjectWriter>(OSABI);
1554a25499bSDylan McKay }
1564a25499bSDylan McKay
1574a25499bSDylan McKay } // end of namespace llvm
158