gcc: Named Address Spaces

1 
1 6.16 Named Address Spaces
1 =========================
1 
1 As an extension, GNU C supports named address spaces as defined in the
1 N1275 draft of ISO/IEC DTR 18037.  Support for named address spaces in
1 GCC will evolve as the draft technical report changes.  Calling
1 conventions for any target might also change.  At present, only the AVR,
1 SPU, M32C, RL78, and x86 targets support address spaces other than the
1 generic address space.
1 
1  Address space identifiers may be used exactly like any other C type
1 qualifier (e.g., 'const' or 'volatile').  See the N1275 document for
1 more details.
1 
1 6.16.1 AVR Named Address Spaces
1 -------------------------------
1 
1 On the AVR target, there are several address spaces that can be used in
1 order to put read-only data into the flash memory and access that data
1 by means of the special instructions 'LPM' or 'ELPM' needed to read from
1 flash.
1 
1  Devices belonging to 'avrtiny' and 'avrxmega3' can access flash memory
1 by means of 'LD*' instructions because the flash memory is mapped into
1 the RAM address space.  There is _no need_ for language extensions like
1 '__flash' or attribute ⇒'progmem' AVR Variable Attributes.  The
1 default linker description files for these devices cater for that
1 feature and '.rodata' stays in flash: The compiler just generates 'LD*'
1 instructions, and the linker script adds core specific offsets to all
1 '.rodata' symbols: '0x4000' in the case of 'avrtiny' and '0x8000' in the
1 case of 'avrxmega3'.  See ⇒AVR Options for a list of respective
1 devices.
1 
1  For devices not in 'avrtiny' or 'avrxmega3', any data including
1 read-only data is located in RAM (the generic address space) because
1 flash memory is not visible in the RAM address space.  In order to
1 locate read-only data in flash memory _and_ to generate the right
1 instructions to access this data without using (inline) assembler code,
1 special address spaces are needed.
1 
1 '__flash'
1      The '__flash' qualifier locates data in the '.progmem.data'
1      section.  Data is read using the 'LPM' instruction.  Pointers to
1      this address space are 16 bits wide.
1 
1 '__flash1'
1 '__flash2'
1 '__flash3'
1 '__flash4'
1 '__flash5'
1      These are 16-bit address spaces locating data in section
1      '.progmemN.data' where N refers to address space '__flashN'.  The
1      compiler sets the 'RAMPZ' segment register appropriately before
1      reading data by means of the 'ELPM' instruction.
1 
1 '__memx'
1      This is a 24-bit address space that linearizes flash and RAM: If
1      the high bit of the address is set, data is read from RAM using the
1      lower two bytes as RAM address.  If the high bit of the address is
1      clear, data is read from flash with 'RAMPZ' set according to the
11      high byte of the address.  ⇒'__builtin_avr_flash_segment' AVR
      Built-in Functions.
1 
1      Objects in this address space are located in '.progmemx.data'.
1 
1  Example
1 
1      char my_read (const __flash char ** p)
1      {
1          /* p is a pointer to RAM that points to a pointer to flash.
1             The first indirection of p reads that flash pointer
1             from RAM and the second indirection reads a char from this
1             flash address.  */
1 
1          return **p;
1      }
1 
1      /* Locate array[] in flash memory */
1      const __flash int array[] = { 3, 5, 7, 11, 13, 17, 19 };
1 
1      int i = 1;
1 
1      int main (void)
1      {
1         /* Return 17 by reading from flash memory */
1         return array[array[i]];
1      }
1 
1 For each named address space supported by avr-gcc there is an equally
1 named but uppercase built-in macro defined.  The purpose is to
1 facilitate testing if respective address space support is available or
1 not:
1 
1      #ifdef __FLASH
1      const __flash int var = 1;
1 
1      int read_var (void)
1      {
1          return var;
1      }
1      #else
1      #include <avr/pgmspace.h> /* From AVR-LibC */
1 
1      const int var PROGMEM = 1;
1 
1      int read_var (void)
1      {
1          return (int) pgm_read_word (&var);
1      }
1      #endif /* __FLASH */
1 
1 Notice that attribute ⇒'progmem' AVR Variable Attributes. locates
1 data in flash but accesses to these data read from generic address
1 space, i.e. from RAM, so that you need special accessors like
1 'pgm_read_byte' from AVR-LibC (http://nongnu.org/avr-libc/user-manual/)
1 together with attribute 'progmem'.
1 
1 Limitations and caveats
1 
1    * Reading across the 64 KiB section boundary of the '__flash' or
1      '__flashN' address spaces shows undefined behavior.  The only
1      address space that supports reading across the 64 KiB flash segment
1      boundaries is '__memx'.
1 
1    * If you use one of the '__flashN' address spaces you must arrange
1      your linker script to locate the '.progmemN.data' sections
1      according to your needs.
1 
1    * Any data or pointers to the non-generic address spaces must be
1      qualified as 'const', i.e. as read-only data.  This still applies
1      if the data in one of these address spaces like software version
1      number or calibration lookup table are intended to be changed after
1      load time by, say, a boot loader.  In this case the right
1      qualification is 'const' 'volatile' so that the compiler must not
1      optimize away known values or insert them as immediates into
1      operands of instructions.
1 
1    * The following code initializes a variable 'pfoo' located in static
1      storage with a 24-bit address:
1           extern const __memx char foo;
1           const __memx void *pfoo = &foo;
1 
1    * On the reduced Tiny devices like ATtiny40, no address spaces are
1      supported.  Just use vanilla C / C++ code without overhead as
1      outlined above.  Attribute 'progmem' is supported but works
1      differently, see ⇒AVR Variable Attributes.
1 
1 6.16.2 M32C Named Address Spaces
1 --------------------------------
1 
1 On the M32C target, with the R8C and M16C CPU variants, variables
1 qualified with '__far' are accessed using 32-bit addresses in order to
1 access memory beyond the first 64 Ki bytes.  If '__far' is used with the
1 M32CM or M32C CPU variants, it has no effect.
1 
1 6.16.3 RL78 Named Address Spaces
1 --------------------------------
1 
1 On the RL78 target, variables qualified with '__far' are accessed with
1 32-bit pointers (20-bit addresses) rather than the default 16-bit
1 addresses.  Non-far variables are assumed to appear in the topmost
1 64 KiB of the address space.
1 
1 6.16.4 SPU Named Address Spaces
1 -------------------------------
1 
1 On the SPU target variables may be declared as belonging to another
1 address space by qualifying the type with the '__ea' address space
1 identifier:
1 
1      extern int __ea i;
1 
1 The compiler generates special code to access the variable 'i'.  It may
1 use runtime library support, or generate special machine instructions to
1 access that address space.
1 
1 6.16.5 x86 Named Address Spaces
1 -------------------------------
1 
1 On the x86 target, variables may be declared as being relative to the
1 '%fs' or '%gs' segments.
1 
1 '__seg_fs'
1 '__seg_gs'
1      The object is accessed with the respective segment override prefix.
1 
1      The respective segment base must be set via some method specific to
1      the operating system.  Rather than require an expensive system call
1      to retrieve the segment base, these address spaces are not
1      considered to be subspaces of the generic (flat) address space.
1      This means that explicit casts are required to convert pointers
1      between these address spaces and the generic address space.  In
1      practice the application should cast to 'uintptr_t' and apply the
1      segment base offset that it installed previously.
1 
1      The preprocessor symbols '__SEG_FS' and '__SEG_GS' are defined when
1      these address spaces are supported.
1