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