1 //===- AVR.cpp ------------------------------------------------------------===// 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 // AVR is a Harvard-architecture 8-bit micrcontroller designed for small 10 // baremetal programs. All AVR-family processors have 32 8-bit registers. 11 // The tiniest AVR has 32 byte RAM and 1 KiB program memory, and the largest 12 // one supports up to 2^24 data address space and 2^22 code address space. 13 // 14 // Since it is a baremetal programming, there's usually no loader to load 15 // ELF files on AVRs. You are expected to link your program against address 16 // 0 and pull out a .text section from the result using objcopy, so that you 17 // can write the linked code to on-chip flush memory. You can do that with 18 // the following commands: 19 // 20 // ld.lld -Ttext=0 -o foo foo.o 21 // objcopy -O binary --only-section=.text foo output.bin 22 // 23 // Note that the current AVR support is very preliminary so you can't 24 // link any useful program yet, though. 25 // 26 //===----------------------------------------------------------------------===// 27 28 #include "InputFiles.h" 29 #include "Symbols.h" 30 #include "Target.h" 31 #include "lld/Common/ErrorHandler.h" 32 #include "llvm/Object/ELF.h" 33 #include "llvm/Support/Endian.h" 34 35 using namespace llvm; 36 using namespace llvm::object; 37 using namespace llvm::support::endian; 38 using namespace llvm::ELF; 39 40 namespace lld { 41 namespace elf { 42 43 namespace { 44 class AVR final : public TargetInfo { 45 public: 46 AVR(); 47 RelExpr getRelExpr(RelType type, const Symbol &s, 48 const uint8_t *loc) const override; 49 void relocate(uint8_t *loc, const Relocation &rel, 50 uint64_t val) const override; 51 }; 52 } // namespace 53 54 AVR::AVR() { noneRel = R_AVR_NONE; } 55 56 RelExpr AVR::getRelExpr(RelType type, const Symbol &s, 57 const uint8_t *loc) const { 58 return R_ABS; 59 } 60 61 void AVR::relocate(uint8_t *loc, const Relocation &rel, uint64_t val) const { 62 switch (rel.type) { 63 case R_AVR_CALL: { 64 uint16_t hi = val >> 17; 65 uint16_t lo = val >> 1; 66 write16le(loc, read16le(loc) | ((hi >> 1) << 4) | (hi & 1)); 67 write16le(loc + 2, lo); 68 break; 69 } 70 default: 71 error(getErrorLocation(loc) + "unrecognized relocation " + 72 toString(rel.type)); 73 } 74 } 75 76 TargetInfo *getAVRTargetInfo() { 77 static AVR target; 78 return ⌖ 79 } 80 81 } // namespace elf 82 } // namespace lld 83