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 relocateOne(uint8_t *loc, RelType type, uint64_t val) const override; 50 }; 51 } // namespace 52 53 AVR::AVR() { noneRel = R_AVR_NONE; } 54 55 RelExpr AVR::getRelExpr(RelType type, const Symbol &s, 56 const uint8_t *loc) const { 57 return R_ABS; 58 } 59 60 void AVR::relocateOne(uint8_t *loc, RelType type, uint64_t val) const { 61 switch (type) { 62 case R_AVR_CALL: { 63 uint16_t hi = val >> 17; 64 uint16_t lo = val >> 1; 65 write16le(loc, read16le(loc) | ((hi >> 1) << 4) | (hi & 1)); 66 write16le(loc + 2, lo); 67 break; 68 } 69 default: 70 error(getErrorLocation(loc) + "unrecognized relocation " + toString(type)); 71 } 72 } 73 74 TargetInfo *getAVRTargetInfo() { 75 static AVR target; 76 return ⌖ 77 } 78 79 } // namespace elf 80 } // namespace lld 81