How do I enable small addressing mode via section pragma?

If you just want to locate some initialized data variables in the small addressable area, you can use the following workflow:

  • Define a ".data_a0" section pragma in the source code:

#pragma clang section data=".data_a0"
int myvar_small = 10;
#pragma clang section data=""
  • Collect input section ".data_a0" into the .sdata output section in the linker script:

SECTIONS
{
    /* Short-addresable data - initialized */
    .sdata : ALIGN(4)
    {
		PROVIDE(__SMALL_DATA__ = . + 0x8000);
        *(.data_a0)
        *(.data_a0.*)
        . = ALIGN(4);
    } > DATA_SDA0 AT > RODATA
}
  • Within the start-up code, initialize A0 address register with the symbol _SMALL_DATA_:

movh.a %a0,hi: _SMALL_DATA_ # %a0 addresses .sdata/.sbss
lea %a0,[%a0]lo: _SMALL_DATA_
  • The section pragma will perform the equivalent of adding attributesection (".data_a0") to all covered global initialized variable definitions.

  • If the linker script collects this input section into .sdata output section, the small addressable mode will be used independently from any compiler option -msmall=<size-limit>.

  • Note that myvar_small needs to be initialized to non-zero value to be recognized as type data in the pragma section statement.

  • For more details, please refer to the question: How should I use relative (small) addressing?.

The __attribute__((fardata)) variable attribute has the highest precedence: if a variable or constant is marked by that attribute, then the data object is excluded from other special addressing mode features. That is, in case you want to exclude certain pieces of code when using the compiler option -msmall<size-limit>.

Example

#define _far __attribute__((fardata))

_far int data = 1;