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