Some ARM processor cores support two different instruction sets. They can run the standard ARM instruction set, where each instruction occupies 32 bits, and also the reduced size Thumb instruction set, where each instruction occupies 16 bits. Thumb instructions are more limited in what they can do compared to ARM instructions, but they can represent a considerable saving in the amount of space occupied by the instructions. It is possible to dynamically switch between the two instruction-sets, thus gaining the advantages of both.
The GNUPro compilers are able to produce code for both the ARM and Thumb instruction sets, but only at a file level of granularity. Thus the programmer can choose whether individual functions should be encoded as either ARM or Thumb instructions, but they cannot specify that specific parts of a function should be ARM or Thumb. The other parts of the GNUPro tools (the assembler and linker and so on), all support mixing ARM and Thumb code at any level.
The GNUPro toolkit has two compilers, one of which produces ARM assembler, and the other produces Thumb assembler. If the programmer wants to use just one instruction set to compile their program then no special procedures need to be followed, other than selecting the correct compiler. If the programmer wants to use both instruction sets in their program, then they must separate the ARM and Thumb parts of their program into separate files and compile each individually, while also specifiying the '-mthumb-interwork' command line flag. When the assembled object files are linked together the linker will generate special code to switch between the two instruction sets whenever a call is made from an ARM function to a Thumb function or vice versa.
Create the following sample source code and save it as 'arm_stuff.c'.
extern int thumb_func (int);
int main (void) { return 7 + thumb_func (7); }
Create the following sample source code and save it as 'thumb_stuff.c'.
First compile the ARM sample code:
Then compile the Thumb sample
code:
% arm-elf-gcc arm_stuff.o thumb_stuff.o -mthumb-interwork -o program |
The '-g' and '-O2' command-line options are optional. They are used here to make the output of the debugger easier to understand.
The following sample debugging session was run on the GNUPro ARM simulator. Although the GNUPro ARM simulator is not a supported platform under eCos, the following sample GDB session demonstrates the resulting code size reduction. The GDB release date, the host configuration, and the 'target' command will vary.
Note how the ARM 'add' instruction at '<main+24>' occupies 4 bytes, whereas the Thumb 'add' instruction at '<thumb_func>' occupies 2 bytes.