User guide

3.3 C and C++ interworking and veneers
You can freely mix C and C++ code compiled for ARM and Thumb, but in ARM architecture v4T small code
segments called veneers are required between the ARM and Thumb code to carry out state changes. The ARM
linker generates these interworking veneers when it detects interworking calls.
3.3.1 Compiling code for interworking
The -apcs /interwork compiler option enables all ARM and Thumb C and C++ compilers to compile modules
containing routines that can be called by routines compiled for the other processor state:
tcc -apcs /interwork
armcc -apcs /interwork
tcpp -apcs /interwork
armcpp -apcs /interwork
Modules that are compiled for interworking on ARM architecture v4T generate slightly larger code, typically 2% larger
for Thumb and less than 1% larger for ARM. There is no difference for ARM architecture v5.
In a leaf function, that is a function whose body contains no function calls, the only change in the code generated by
the compiler is to replace MOV pc,lr with BX lr. The MOV instruction does not cause the necessary state change.
In nonleaf functions built for ARM architecture v4T, the Thumb compiler must replace, for example, the single
instruction:
POP {r4,r5,pc}
with the sequence:
POP {r4,r5}
POP {r3}
BX r3
This has a small effect on performance. Compile all source modules for interworking, unless you are sure they will
never be used with interworking.
The -apcs /interwork option also sets the interwork attribute for the code area the modules are compiled into.
The linker detects this attribute and inserts the appropriate veneer.
Note
ARM code compiled for interworking can only be used on ARM architecture v4T, or v5 and above, because other
processors do not implement the BX instruction.
Use the armlink -info veneers option to find the amount of space taken by the veneers.
C interworking example
Example 3-3 shows a Thumb routine that carries out an interworking call to an ARM subroutine. The ARM subroutine
call makes an interworking call to printf() in the Thumb library. These two modules are provided in
Examples\Interwork as thumbmain.c and armsub.c.
Example 3-3
/**********************
* thumbmain.c *
**********************/
#include <stdio.h>
extern void arm_function(void);
int main(void)
{
printf("Hello from Thumb World\n");
arm_function();
printf("And goodbye from Thumb World\n");
return (0);
}
/**********************
* armsub.c *
**********************/
#include <stdio.h>
void arm_function(void)
{
printf("Hello and Goodbye from ARM world\n");
}
Interworking ARM and Thumb
Copyright ?1999 2001 ARM Limited 3-6