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
14 namespace llvm {
15 namespace 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`.
26 enum 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
133 namespace 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.
adjustBranchTarget(T & val)141 template <typename T> inline void adjustBranchTarget(T &val) { val >>= 1; }
142
143 } // end of namespace fixups
144 }
145 } // end of namespace llvm::AVR
146
147 #endif // LLVM_AVR_FIXUP_KINDS_H
148