148 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_AVR_FIXUP_KINDS_H10#define LLVM_AVR_FIXUP_KINDS_H11 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 relocation20/// one can have multiple fixup types for a given relocation and thus need21/// to be uniquely named.22///23/// \note This table *must* be in the same order of24/// 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 conditional31 /// branches which take 7-bit targets (BRNE,BRGT,etc).32 fixup_7_pcrel,33 /// A 12-bit PC-relative fixup for the family of branches34 /// which take 12-bit targets (RJMP,RCALL,etc).35 /// \note Although the fixup is labelled as 13 bits, it36 /// is actually only encoded in 12. The reason for37 /// The nonmenclature is that AVR branch targets are38 /// rightshifted by 1, because instructions are always39 /// 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` instruction52 /// 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` instruction55 /// 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` instruction58 /// 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` instruction61 /// 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` instruction65 /// 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` instruction68 /// 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` instruction71 /// 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` instruction74 /// 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` instruction78 /// 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` instruction81 /// with the upper 8 bits of a 16-bit program memory address value (bits82 /// 8-15).83 fixup_hi8_ldi_pm,84 /// Replaces the immediate operand of a 16-bit `Rd, K` instruction85 /// with the upper 8 bits of a 24-bit program memory address value (bits86 /// 16-23).87 fixup_hh8_ldi_pm,88 89 /// Replaces the immediate operand of a 16-bit `Rd, K` instruction90 /// with the lower 8 bits of a negated 16-bit program memory address value91 /// (bits 0-7).92 fixup_lo8_ldi_pm_neg,93 /// Replaces the immediate operand of a 16-bit `Rd, K` instruction94 /// with the upper 8 bits of a negated 16-bit program memory address value95 /// (bits 8-15).96 fixup_hi8_ldi_pm_neg,97 /// Replaces the immediate operand of a 16-bit `Rd, K` instruction98 /// with the upper 8 bits of a negated 24-bit program memory address value99 /// (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 // Marker129 LastTargetFixupKind,130 NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind131};132 133namespace fixups {134 135/// Adjusts the value of a branch target.136/// All branch targets in AVR are rightshifted by 1 to take advantage137/// of the fact that all instructions are aligned to addresses of size138/// 2, so bit 0 of an address is always 0. This gives us another bit139/// 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 fixups144} // namespace AVR145} // namespace llvm146 147#endif // LLVM_AVR_FIXUP_KINDS_H148