@@ -231,85 +231,139 @@ in AVR instruction operands. The general syntax is the following:
modifier(relocatable-expression)
@end smallexample
+When the argument of a modifier is not computable at assemble time,
+then the assembler has to encode the expression in an abstract form
+using some target-specific @emph{reloc}. The consequence is that only
+a very limited number of argument expressions is supported when they
+are not computable at assemble time.
+
+@cindex symbol modifiers, AVR
@table @code
-@cindex symbol modifiers
+@cindex lo8, AVR
@item lo8
+Bits 0 through 7 of an expression as an 8-bit relocatable expression.
-This modifier allows you to use bits 0 through 7 of
-an address expression as an 8 bit relocatable expression.
-
+@cindex hi8, AVR
@item hi8
-
-This modifier allows you to use bits 7 through 15 of an address expression
-as an 8 bit relocatable expression. This is useful with, for example, the
-AVR @samp{ldi} instruction and @samp{lo8} modifier.
-
-For example
+Bits 8 through 15 of an expression as an 8-bit relocatable expression.
+This is useful with instructions that have an immediate operand, for example:
@smallexample
-ldi r26, lo8(sym+10)
-ldi r27, hi8(sym+10)
+;; my_string is an array of 8-bit values in RAM.
+;; Load the N-th element to R24 where the 16-bit
+;; value N is provided in the Z register (r30 and r31).
+subi r30, lo8(-(my_array))
+sbci r31, hi8(-(my_array))
+ld r24, Z
@end smallexample
-@item hh8
-
-This modifier allows you to use bits 16 through 23 of
-an address expression as an 8 bit relocatable expression.
-Also, can be useful for loading 32 bit constants.
-
+@cindex hlo8, AVR
+@cindex hh8, AVR
@item hlo8
+@itemx hh8
+Bits 16 through 23 of an expression as an 8-bit relocatable expression.
-Synonym of @samp{hh8}.
-
+@cindex hhi8, AVR
@item hhi8
-
-This modifier allows you to use bits 24 through 31 of
-an expression as an 8 bit expression. This is useful with, for example, the
-AVR @samp{ldi} instruction and @samp{lo8}, @samp{hi8}, @samp{hlo8},
-@samp{hhi8}, modifier.
-
-For example
+Bits 24 through 31 of an expression as an 8-bit relocatable expression.
+
+@cindex gs, AVR
+@item gs
+A function address divided by 2 in order to get a word addresses.
+@b{G}enerate a @b{s}tub (linker trampoline) as needed.
+This is required to calculate the address of a code label on devices
+with more than 128 KiB of program memory without the need for code
+addresses wider than 16 bits. See
+@uref{https://gcc.gnu.org/onlinedocs/gcc/AVR-Options.html#eind,,GCC documentation}
+for the rationale.
+
+On devices with less program memory, @code{gs()} behaves like @code{pm()}.
+
+The following example loads the 16-bit address of @samp{func}.
+This will always be a 16-bit address, even on devices with a 3-byte PC.
+With a 3-byte PC, and when the target address is not reachable by an
+@code{EICALL} instruction, the linker will @b{g}enerate a @b{s}tub in the
+@code{.trampolines} section. That stub contains a @samp{JMP func} instruction.
+
+Notice that the compiler never sets @code{EIND}. The
+@uref{https://github.com/avrdudes/avr-libc/blob/main/crt1/gcrt1.S,,startup code from AVR-LibC}
+sets @code{EIND} to the value of @samp{hh8(pm(__vectors))}, and hence
+only labels that satisfy
+@smallexample
+hh8(pm(label)) == EIND
+@end smallexample
+are reachable by @code{EICALL} resp.@: @code{EIJMP}.
+All other labels will get their stub, so that the following code
+will work in all cases:
@smallexample
-ldi r26, lo8(285774925)
-ldi r27, hi8(285774925)
-ldi r28, hlo8(285774925)
-ldi r29, hhi8(285774925)
-; r29,r28,r27,r26 = 285774925
+ldi r30, lo8(gs(func))
+ldi r31, hi8(gs(func))
+#idef __AVR_HAVE_EIJMP_EICALL__
+ eicall
+#else
+ icall
+#endif
@end smallexample
+@cindex pm, AVR
+@cindex pm_lo8, AVR
@item pm_lo8
-
-This modifier allows you to use bits 0 through 7 of
-an address expression as an 8 bit relocatable expression.
+Bits 1 through 8 of an expression as an 8-bit relocatable expression.
This modifier is useful for addressing data or code from
-Flash/Program memory by two-byte words. The use of @samp{pm_lo8}
-is similar to @samp{lo8}.
+Flash/Program memory with a word address.
+@cindex pm_hi8, AVR
@item pm_hi8
-
-This modifier allows you to use bits 8 through 15 of
-an address expression as an 8 bit relocatable expression.
+Bits 9 through 16 of an expression as an 8-bit relocatable expression.
This modifier is useful for addressing data or code from
-Flash/Program memory by two-byte words.
+Flash/Program memory with a word address.
-For example, when setting the AVR @samp{Z} register with the @samp{ldi}
-instruction for subsequent use by the @samp{ijmp} instruction:
+@cindex pm_hh8, AVR
+@item pm_hh8
+Bits 17 through 24 of an expression as an 8-bit relocatable expression.
+This modifier is useful for addressing data or code from
+Flash/Program memory with a word address.
+
+The code below performs an indirect call by hand to function @samp{func}
+by means of the following steps:
+
+@enumerate
+@item
+Put the word address of the @samp{1:} label on the stack.
+This is the return address.
+@item
+Put the word address of @samp{func} on the stack.
+@item
+Invoke that address by means of a @code{RET} instruction.
+@item
+The @code{RET} instruction at the end of @samp{func} will
+jump to the word address of the @samp{1:} label.
+@end enumerate
@smallexample
-ldi r30, pm_lo8(sym)
-ldi r31, pm_hi8(sym)
-ijmp
+;; Push the word address of the return location.
+ldi r24, pm_lo8(1f) $ push r24
+ldi r24, pm_hi8(1f) $ push r24
+#ifdef __AVR_3_BYTE_PC__
+ldi r24, pm_hh8(1f) $ push r24
+#endif
+
+;; Push the word address of func using alternative syntax.
+ldi r24, lo8(pm(func)) $ push r24
+ldi r24, hi8(pm(func)) $ push r24
+#ifdef __AVR_3_BYTE_PC__
+ldi r24, hh8(pm(func)) $ push r24
+#endif
+
+;; Indirect jump to the word address on the stack
+ret
+
+;; The return location that func will return to.
+1:
@end smallexample
-@item pm_hh8
-
-This modifier allows you to use bits 15 through 23 of
-an address expression as an 8 bit relocatable expression.
-This modifier is useful for addressing data or code from
-Flash/Program memory by two-byte words.
-
@end table
@node AVR Opcodes