//===-- AVRFixupKinds.h - AVR Specific Fixup Entries ------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_AVR_FIXUP_KINDS_H #define LLVM_AVR_FIXUP_KINDS_H #include "llvm/MC/MCFixup.h" namespace llvm { namespace AVR { /// The set of supported fixups. /// /// Although most of the current fixup types reflect a unique relocation /// one can have multiple fixup types for a given relocation and thus need /// to be uniquely named. /// /// \note This table *must* be in the same order of /// MCFixupKindInfo Infos[AVR::NumTargetFixupKinds] /// in `AVRAsmBackend.cpp`. enum Fixups { /// A 32-bit AVR fixup. fixup_32 = FirstTargetFixupKind, /// A 7-bit PC-relative fixup for the family of conditional /// branches which take 7-bit targets (BRNE,BRGT,etc). fixup_7_pcrel, /// A 12-bit PC-relative fixup for the family of branches /// which take 12-bit targets (RJMP,RCALL,etc). /// \note Although the fixup is labelled as 13 bits, it /// is actually only encoded in 12. The reason for /// The nonmenclature is that AVR branch targets are /// rightshifted by 1, because instructions are always /// aligned to 2 bytes, so the 0'th bit is always 0. /// This way there is 13-bits of precision. fixup_13_pcrel, /// A 16-bit address. fixup_16, /// A 16-bit program memory address. fixup_16_pm, /// Replaces the 8-bit immediate with another value. fixup_ldi, /// Replaces the immediate operand of a 16-bit `Rd, K` instruction /// with the lower 8 bits of a 16-bit value (bits 0-7). fixup_lo8_ldi, /// Replaces the immediate operand of a 16-bit `Rd, K` instruction /// with the upper 8 bits of a 16-bit value (bits 8-15). fixup_hi8_ldi, /// Replaces the immediate operand of a 16-bit `Rd, K` instruction /// with the upper 8 bits of a 24-bit value (bits 16-23). fixup_hh8_ldi, /// Replaces the immediate operand of a 16-bit `Rd, K` instruction /// with the upper 8 bits of a 32-bit value (bits 24-31). fixup_ms8_ldi, /// Replaces the immediate operand of a 16-bit `Rd, K` instruction /// with the lower 8 bits of a negated 16-bit value (bits 0-7). fixup_lo8_ldi_neg, /// Replaces the immediate operand of a 16-bit `Rd, K` instruction /// with the upper 8 bits of a negated 16-bit value (bits 8-15). fixup_hi8_ldi_neg, /// Replaces the immediate operand of a 16-bit `Rd, K` instruction /// with the upper 8 bits of a negated 24-bit value (bits 16-23). fixup_hh8_ldi_neg, /// Replaces the immediate operand of a 16-bit `Rd, K` instruction /// with the upper 8 bits of a negated 32-bit value (bits 24-31). fixup_ms8_ldi_neg, /// Replaces the immediate operand of a 16-bit `Rd, K` instruction /// with the lower 8 bits of a 16-bit program memory address value (bits 0-7). fixup_lo8_ldi_pm, /// Replaces the immediate operand of a 16-bit `Rd, K` instruction /// with the upper 8 bits of a 16-bit program memory address value (bits /// 8-15). fixup_hi8_ldi_pm, /// Replaces the immediate operand of a 16-bit `Rd, K` instruction /// with the upper 8 bits of a 24-bit program memory address value (bits /// 16-23). fixup_hh8_ldi_pm, /// Replaces the immediate operand of a 16-bit `Rd, K` instruction /// with the lower 8 bits of a negated 16-bit program memory address value /// (bits 0-7). fixup_lo8_ldi_pm_neg, /// Replaces the immediate operand of a 16-bit `Rd, K` instruction /// with the upper 8 bits of a negated 16-bit program memory address value /// (bits 8-15). fixup_hi8_ldi_pm_neg, /// Replaces the immediate operand of a 16-bit `Rd, K` instruction /// with the upper 8 bits of a negated 24-bit program memory address value /// (bits 16-23). fixup_hh8_ldi_pm_neg, /// A 22-bit fixup for the target of a `CALL k` or `JMP k` instruction. fixup_call, fixup_6, /// A symbol+addr fixup for the `LDD +, " family of instructions. fixup_6_adiw, fixup_lo8_ldi_gs, fixup_hi8_ldi_gs, fixup_8, fixup_8_lo8, fixup_8_hi8, fixup_8_hlo8, fixup_diff8, fixup_diff16, fixup_diff32, fixup_lds_sts_16, /// A 6-bit port address. fixup_port6, /// A 5-bit port address. fixup_port5, // Marker LastTargetFixupKind, NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind }; namespace fixups { /// Adjusts the value of a branch target. /// All branch targets in AVR are rightshifted by 1 to take advantage /// of the fact that all instructions are aligned to addresses of size /// 2, so bit 0 of an address is always 0. This gives us another bit /// of precision. /// \param [in,out] val The target to adjust. template inline void adjustBranchTarget(T &val) { val >>= 1; } } // end of namespace fixups } // namespace AVR } // namespace llvm #endif // LLVM_AVR_FIXUP_KINDS_H