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