12.8.18. Interworking ARM and Thumb

You can mix C and C++ code for ARM and Thumb, provided that the code conforms to the requirements of the ARM and Thumb Procedure Call Standards. See ARM-Thumb Procedure Call Standard (ATPCS) Specification for details.

The ARM linker detects when ARM and Thumb code is mixed and generates small code segments, called veneers, that control the change in state between ARM and Thumb.

If you compile a module for interworking, it generates slightly larger code for Thumb, around 2%, and marginally larger code for ARM. Use the linker option -info to find the amount of space taken up by the veneers. Disabled by default, this can be set in the BUILD group for your interworking project.

Note

ARM code compiled for interworking cannot be used on ARM architecture-based processors that are not Thumb-capable, for example StrongARM, because these processors do not implement the BX (Branch Exchange) instruction.

This section contains examples of making changes to the example project interworking.prj located in the examples_directory\interworking directory in your root installation. You might want to make a backup of the project base directory before following the examples so that the default files and settings can be restored.

The examples describe:

To see an example of interworking ARM and Thumb code:

  1. Select Project → Open Project... from the default Code window main menu to open the example project interworking.prj located in the examples_directory\interworking directory of your root installation.

  2. Open the source file hello_goodbye.c so that it is displayed in the File Editor pane.

  3. Add a new line before the call to the Thumb routine, for example:

    24 fprintf(stdout,"Now in Thumb routine\n");
    
    25 thumbtest();
    
  4. Select Tools → Build... to rebuild the application. This displays a list selection box where you can confirm the source file that has been changed.

  5. Click OK to confirm the save and rebuild the application.

  6. Connect to the processor core using RVI-ME.

  7. Load the image interworking.axf, and run the application. The StdIO tab, in the Output pane, displays the results.

Note

The interworking example project contains an unused deck of cards to show how RealView Debugger displays structures and arrays, see hello_goodbye.c. This is not specific to interworking.

Setting compiler options for interworking

To set compiler options:

  1. Select Project → Project Properties... to display the Project Properties window. Expand the entries, shown in Figure 12.11.

    Figure 12.11. Project Properties window for interworking project

    Project Properties window for interworking project
  2. Confirm the compiler options for the interworking example project.

    The *Interworking settings value is set to enabled for the *COMPILE=arm group. This sets the -apcs /interwork compiler option. This means that the ARM compilers can compile modules containing routines called by other routines compiled for Thumb state.

    Similarly, expand the *COMPILE=thumb group to see the APCS setting enabled for routines compiled for ARM state.

  3. The interworking example project defines two enabled COMPILE groups, shown in Figure 12.11:

    • COMPILE=arm specifies the ARM C compiler, that is armcc or armcc --arm, to compile ANSI C source into 32-bit ARM code

    • COMPILE=thumb specifies the Thumb C compiler, that is armcc --thumb, to compile ANSI C source into 16-bit Thumb code.

    The COMPILE=arm_cpp settings value is grayed out showing that it is disabled for this project. This specifies the ARM C++ compiler, that is armcc --cpp, to compile ANSI C++ or EC++ source into 32-bit ARM code.

  4. If you want to use software stack checking, this can be set in this settings values page. Set to the default for the compiler, you can force checking on or off. Right-click on the Stack_checking setting in the Settings Values pane, and select enabled.

    Ensure that all ARM and Thumb modules are compiled to the same standard if they are to be interworked. Failure to do this results in a warning from the compiler, for example:

    Error: L6242E: Cannot link object thumbtest.o as its attributes are incompatible with the image attributes.   ... stack-checked clashes with not-stack-checked.
    
  5. Select File → Save and Close to regenerate the makefile(s) for the project, and close the Project Properties window.

  6. Select Tools → Build... to rebuild the application.

Displaying code sizes

To create a file containing code sizes for your interworking project:

  1. Select Project → Project Properties... to display the Project Properties window.

  2. Right-click on the *BUILD group at the bottom of the List of Entries pane, and select Expand whole Tree from the context menu. This displays the contents in the Settings Values pane.

  3. Select the Listings group in the List of Entries pane.

  4. Right-click on the Listing_file setting in the Settings Values pane, and select Edit as Filename from the context menu. Enter the path of a text file to accept the linker output, for example examples_directory\interworking\listing.txt.

  5. Select the Messages group in the List of Entries pane.

  6. Right-click on the Sizes setting, in the Settings Values pane, and select both from the options list. This displays details and totals size information.

  7. Right-click on the Veneers setting, in the Settings Values pane, and select enabled from the options list.

  8. Select File → Save and Close to regenerate the makefile(s) for the project, and close the Project Properties window.

  9. Select Tools → Build... to rebuild the application.

  10. Open the linker messages file in the File Editor pane and view the contents.

Copyright © 2003, 2004 ARM Limited. All rights reserved.ARM DUI 0234B
Non-Confidential