• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
adjustBranchTarget(T & val)142 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
149