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 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 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. |
141 | template <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 | |