1//===-- AVRFixupKinds.h - AVR Specific Fixup Entries ------------*- C++ -*-===//
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#ifndef LLVM_AVR_FIXUP_KINDS_H
10#define LLVM_AVR_FIXUP_KINDS_H
11
12#include "llvm/MC/MCFixup.h"
13
14namespace llvm {
15namespace AVR {
16
17/// The set of supported fixups.
18///
19/// Although most of the current fixup types reflect a unique relocation
20/// one can have multiple fixup types for a given relocation and thus need
21/// to be uniquely named.
22///
23/// \note This table *must* be in the same order of
24///       MCFixupKindInfo Infos[AVR::NumTargetFixupKinds]
25///       in `AVRAsmBackend.cpp`.
26enum Fixups {
27  /// A 32-bit AVR fixup.
28  fixup_32 = FirstTargetFixupKind,
29
30  /// A 7-bit PC-relative fixup for the family of conditional
31  /// branches which take 7-bit targets (BRNE,BRGT,etc).
32  fixup_7_pcrel,
33  /// A 12-bit PC-relative fixup for the family of branches
34  /// which take 12-bit targets (RJMP,RCALL,etc).
35  /// \note Although the fixup is labelled as 13 bits, it
36  ///       is actually only encoded in 12. The reason for
37  ///       The nonmenclature is that AVR branch targets are
38  ///       rightshifted by 1, because instructions are always
39  ///       aligned to 2 bytes, so the 0'th bit is always 0.
40  ///       This way there is 13-bits of precision.
41  fixup_13_pcrel,
42
43  /// A 16-bit address.
44  fixup_16,
45  /// A 16-bit program memory address.
46  fixup_16_pm,
47
48  /// Replaces the 8-bit immediate with another value.
49  fixup_ldi,
50
51  /// Replaces the immediate operand of a 16-bit `Rd, K` instruction
52  /// with the lower 8 bits of a 16-bit value (bits 0-7).
53  fixup_lo8_ldi,
54  /// Replaces the immediate operand of a 16-bit `Rd, K` instruction
55  /// with the upper 8 bits of a 16-bit value (bits 8-15).
56  fixup_hi8_ldi,
57  /// Replaces the immediate operand of a 16-bit `Rd, K` instruction
58  /// with the upper 8 bits of a 24-bit value (bits 16-23).
59  fixup_hh8_ldi,
60  /// Replaces the immediate operand of a 16-bit `Rd, K` instruction
61  /// with the upper 8 bits of a 32-bit value (bits 24-31).
62  fixup_ms8_ldi,
63
64  /// Replaces the immediate operand of a 16-bit `Rd, K` instruction
65  /// with the lower 8 bits of a negated 16-bit value (bits 0-7).
66  fixup_lo8_ldi_neg,
67  /// Replaces the immediate operand of a 16-bit `Rd, K` instruction
68  /// with the upper 8 bits of a negated 16-bit value (bits 8-15).
69  fixup_hi8_ldi_neg,
70  /// Replaces the immediate operand of a 16-bit `Rd, K` instruction
71  /// with the upper 8 bits of a negated negated 24-bit value (bits 16-23).
72  fixup_hh8_ldi_neg,
73  /// Replaces the immediate operand of a 16-bit `Rd, K` instruction
74  /// with the upper 8 bits of a negated negated 32-bit value (bits 24-31).
75  fixup_ms8_ldi_neg,
76
77  /// Replaces the immediate operand of a 16-bit `Rd, K` instruction
78  /// with the lower 8 bits of a 16-bit program memory address value (bits 0-7).
79  fixup_lo8_ldi_pm,
80  /// Replaces the immediate operand of a 16-bit `Rd, K` instruction
81  /// with the upper 8 bits of a 16-bit program memory address value (bits
82  /// 8-15).
83  fixup_hi8_ldi_pm,
84  /// Replaces the immediate operand of a 16-bit `Rd, K` instruction
85  /// with the upper 8 bits of a 24-bit program memory address value (bits
86  /// 16-23).
87  fixup_hh8_ldi_pm,
88
89  /// Replaces the immediate operand of a 16-bit `Rd, K` instruction
90  /// with the lower 8 bits of a negated 16-bit program memory address value
91  /// (bits 0-7).
92  fixup_lo8_ldi_pm_neg,
93  /// Replaces the immediate operand of a 16-bit `Rd, K` instruction
94  /// with the upper 8 bits of a negated 16-bit program memory address value
95  /// (bits 8-15).
96  fixup_hi8_ldi_pm_neg,
97  /// Replaces the immediate operand of a 16-bit `Rd, K` instruction
98  /// with the upper 8 bits of a negated 24-bit program memory address value
99  /// (bits 16-23).
100  fixup_hh8_ldi_pm_neg,
101
102  /// A 22-bit fixup for the target of a `CALL k` or `JMP k` instruction.
103  fixup_call,
104
105  fixup_6,
106  /// A symbol+addr fixup for the `LDD <x>+<n>, <r>" family of instructions.
107  fixup_6_adiw,
108
109  fixup_lo8_ldi_gs,
110  fixup_hi8_ldi_gs,
111
112  fixup_8,
113  fixup_8_lo8,
114  fixup_8_hi8,
115  fixup_8_hlo8,
116
117  fixup_diff8,
118  fixup_diff16,
119  fixup_diff32,
120
121  fixup_lds_sts_16,
122
123  /// A 6-bit port address.
124  fixup_port6,
125  /// A 5-bit port address.
126  fixup_port5,
127
128  // Marker
129  LastTargetFixupKind,
130  NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
131};
132
133namespace fixups {
134
135/// Adjusts the value of a branch target.
136/// All branch targets in AVR are rightshifted by 1 to take advantage
137/// of the fact that all instructions are aligned to addresses of size
138/// 2, so bit 0 of an address is always 0. This gives us another bit
139/// of precision.
140/// \param [in,out] val The target to adjust.
141template <typename T> inline void adjustBranchTarget(T &val) { val >>= 1; }
142
143} // end of namespace fixups
144} // namespace AVR
145} // namespace llvm
146
147#endif // LLVM_AVR_FIXUP_KINDS_H
148