AVR.cpp revision 360784
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
35using namespace llvm;
36using namespace llvm::object;
37using namespace llvm::support::endian;
38using namespace llvm::ELF;
39
40namespace lld {
41namespace elf {
42
43namespace {
44class AVR final : public TargetInfo {
45public:
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
53AVR::AVR() { noneRel = R_AVR_NONE; }
54
55RelExpr AVR::getRelExpr(RelType type, const Symbol &s,
56                        const uint8_t *loc) const {
57  return R_ABS;
58}
59
60void 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
74TargetInfo *getAVRTargetInfo() {
75  static AVR target;
76  return &target;
77}
78
79} // namespace elf
80} // namespace lld
81