Additional Small Data Sections

The PowerPC EABI specification mandates that compliant build tools predefine three small data sections. The Properties > C/C++ Build > Settings > Tool Settings > PowerPC Linker > Input panel lets you specify the address at which the CodeWarrior linker puts two of these sections (if the default locations are unsatisfactory).

CodeWarrior Development Studio, lets you create small data sections in addition to those mandated by the PowerPC EABI specification. The CodeWarrior tools let you specify that the contents of a given user-defined section will be accessed by the small data base register selected from the available non-volatile registers. To do this, you use a combination of source code statements and linker command file directives.

To create one additional small data area, follow these steps:

  1. Open the CodeWarrior project in which you want to create an additional small data section.
  2. Select the build target in which you want to create an additional small data section.
  3. Select Project > Properties.

    The IDE displays the Properties for <Project> window.

  4. In the left pane of the Properties for <Project>, select PowerPC Compiler > Preprocessor.

  5. Click Browse to open the prefix file whose name appears in the Prefix File text box in an editor window.
  6. Add the statements that define a small data section to the top of the prefix file:
    1. Add a statement that creates a global register variable.

      For example, to create a global register variable for register 14, add this statement to the prefix file:

      // _dummy does not have to be defined extern int _dummy asm("r14");
    2. Create a user-defined section using the section pragma; include the clause data_mode = sda_rel so the section can use small data area addressing.

      For example:

      // you do not have to use the names in this example
      // .red is the initialized part of the section
      // .blue is the uninitialized part of the section#pragma section RW ".red" ".blue" data_mode = sda_rel
      Note: If you want your small data area to be the default section for all small data, use the following form of the section pragma instead of the one above:#pragma section sdata_type ".red" "blue" data_mode = sda_rel
  7. Save the prefix file and close the editor window.
  8. In each header or source file that declares or defines a global variable that you want to put in a small data section, put the storage-class modifier __declspec(section "initialized_small_sect_nm") in front of the definition or declaration.

    For example, the statement:

    __declspec(section ".red") int x = 5;

    instructs the compiler to put the global variable x into the small data section named .red

    CAUTION:
    The section name specified in the __declspec(section <section_name>) statement must be the name of an initialized data section. It is an error to use the uninitialized data section name.
    Note: The semantics of __declspec(section ".sdata") int x; is to use the section pair .sdata and .sbss to store x. The location where x is stored is determined by whether or not x is explicitly initialized.
    Note: If you want your small data section to be the default section for all small data, use #pragma section sdata_type ".foo" ".bar" data_mode = sda_relUse __declspec(section ".foo")only when the object is greater than the size threshold for small data.
  9. On the Tool Settings tab, select PowerPC Linker > Input .

  10. Click Browse to specify a Link Command File (.lcf).

  11. On the Tool Settings tab, select PowerPC CPU.

  12. From the Code Model listbox, select Absolute Addressing.
  13. From the ABI listbox, select EABI .
  14. Click OK.

    The IDE saves your settings and closes theProperties for <Project> window.

  15. Modify the project's linker command file such that it instructs the linker to use the global register declared above as the base register for your new small data section.

    To do this, follow these steps:

    1. In the linker command file, add two REGISTER directives, one for the initialized part of the small data section and one for uninitialized part.

      For example, to make register 14 the base register, add statements like these:

      .red REGISTER(14) : {} > ram
      .blue REGISTER(14) : {} > ram
    2. Add the linker command file to each build target in which you want to use the new small data section.
  16. Open the CodeWarrior project for the runtime library used by your project.
  17. In the build target listbox of the runtime library project window, select the build target of the runtime library that your main project uses.
  18. Open this build target's prefix file in a CodeWarrior editor window.
  19. Add the same statements to this prefix file that you added to the prefix file of the main project.
  20. Save the prefix file and close the editor window.
  21. Open __start.c in a CodeWarrior editor window.
  22. Find the string __init_registers(void) and add statements that initialize the small data section base register you are using near the end of this function (immediately above the terminating blr instruction).

    For example, to initialize register 14, add these statements:

    lis r14, _SDA14_BASE_@ha
    addi r14, r14, _SDA14_BASE_@l
  23. Save __start.c and close the editor window.
  24. Open __ppc_eabi_linker.h in a CodeWarrior editor window.
  25. Find the string _SDA_BASE_[] in this file and add this statement after the block of statements that follow this string:
    // SDAnn_BASE is defined by the linker if
    // the REGISTER(nn) directive appears in the .lcf file
    __declspec(section ".init") extern char _SDA14_BASE_[];
  26. Save __ppc_eabi_linker.h and close the editor window.
  27. Return to your main project.
  28. Select Project > Build Project.

    The IDE builds your project.

    You can now use the new small data section in this project.

    Note: You can create more small data segments by following the procedure above. Remember, however, that for each small data section created, the compiler loses one non-volatile register to use for other purposes.
Related information
Predefined Sections
Linker Map File
Deadstripping
CodeWarrior Linker Command File (LCF)
Creating an LCF from Scratch
Relocating Code in ROM
Relocating Code and Data in Internal RAM
Relocating Code and Data in External MRAM
Unique LCF Examples
Linker Command File Commands