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