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 14namespace llvm { 15namespace 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`. 26enum 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 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 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 133namespace 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. 141template <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