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.
adjustBranchTarget(T & val)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