Next: Zero Length, Previous: Fixed-Point, Up: C Extensions

### 6.16 Named Address Spaces

As an extension, the GNU C compiler supports named address spaces as defined in the N1275 draft of ISO/IEC DTR 18037. Support for named address spaces in GCC will evolve as the draft technical report changes. Calling conventions for any target might also change. At present, only the AVR, SPU, M32C, and RL78 targets support address spaces other than the generic address space.

Address space identifiers may be used exactly like any other C type qualifier (e.g., `const` or `volatile`). See the N1275 document for more details.

#### 6.16.1 AVR Named Address Spaces

On the AVR target, there are several address spaces that can be used in order to put read-only data into the flash memory and access that data by means of the special instructions `LPM` or `ELPM` needed to read from flash.

Per default, any data including read-only data is located in RAM (the generic address space) so that non-generic address spaces are needed to locate read-only data in flash memory and to generate the right instructions to access this data without using (inline) assembler code.

`__flash`
  The `__flash` qualifier will locate data in the `.progmem.data` section. Data will be read using the `LPM` instruction. Pointers to this address space are 16 bits wide.
`__flash1`
`__flash2`
`__flash3`
`__flash4`
`__flash5`
  These are 16-bit address spaces locating data in section `.progmem` N`.data` where N refers to address space `__flash` N. The compiler will set the `RAMPZ` segment register approptiately before reading data by means of the `ELPM` instruction.
`__memx`
  This is a 24-bit address space that linearizes flash and RAM: If the high bit of the address is set, data is read from RAM using the lower two bytes as RAM address. If the high bit of the address is clear, data is read from flash with `RAMPZ` set according to the high byte of the address.

  Objects in this address space will be located in `.progmemx.data`.

Example

         char my_read (const __flash char ** p)
         {
             /* p is a pointer to RAM that points to a pointer to flash.
                The first indirection of p will read that flash pointer
                from RAM and the second indirection reads a char from this
                flash address.  */

             return **p;
         }

         /* Locate array[] in flash memory */
         const __flash int array[] = { 3, 5, 7, 11, 13, 17, 19 };

         int i = 1;

         int main (void)
         {
            /* Return 17 by reading from flash memory */
            return array[array[i]];
         }

For each named address space supported by avr-gcc there is an equally named but uppercase built-in macro defined. The purpose is to facilitate testing if respective address space support is available or not:

         #ifdef __FLASH
         const __flash int var = 1;

         int read_var (void)
         {
             return var;
         }
         #else
         #include <avr/pgmspace.h> /* From AVR-LibC */

         const int var PROGMEM = 1;

         int read_var (void)
         {
             return (int) pgm_read_word (&var);
         }
         #endif /* __FLASH */

Notice that attribute `progmem` locates data in flash but accesses to these data will read from generic address space, i.e. from RAM, so that you need special accessors like `pgm_read_byte` from AVR-LibC together with attribute `progmem`.

Limitations and caveats

- Reading across the 64 KiB section boundary of the `__flash` or `__flash` N address spaces will show undefined behaviour. The only address space that supports reading across the 64 KiB flash segment boundaries is `__memx`.
- If you use one of the `__flash` N address spaces you will have to arrange your linker skript to locate the `.progmem` N`.data` sections according to your needs.
- Any data or pointers to the non-generic address spaces must be qualified as `const`, i.e. as read-only data. This still applies if the data in one of these address spaces like software version number or calibration lookup table are intended to be changed after load time by, say, a boot loader. In this case the right qualification is `const` `volatile` so that the compiler must not optimize away known values or insert them as immediates into operands of instructions.
- Code like the following is not yet supported because of missing support in avr-binutils, see PR13503.

                extern const __memx char foo;
                const __memx void *pfoo = &foo;

  The code will throw an assembler warning and the high byte of `pfoo` will be initialized with `0`, i.e. the initialization will be as if `foo` was located in the first 64 KiB chunk of flash.

#### 6.16.2 M32C Named Address Spaces

On the M32C target, with the R8C and M16C cpu variants, variables qualified with `__far` are accessed using 32-bit addresses in order to access memory beyond the first 64 Ki bytes. If `__far` is used with the M32CM or M32C cpu variants, it has no effect.

#### 6.16.3 RL78 Named Address Spaces

On the RL78 target, variables qualified with `__far` are accessed with 32-bit pointers (20-bit addresses) rather than the default 16-bit addresses. Non-far variables are assumed to appear in the topmost 64 KiB of the address space.

#### 6.16.4 SPU Named Address Spaces

On the SPU target variables may be declared as belonging to another address space by qualifying the type with the `__ea` address space identifier:

         extern int __ea i;

When the variable `i` is accessed, the compiler will generate special code to access this variable. It may use runtime library support, or generate special machine instructions to access that address space.