| |||
| Home > ARM Compiler Reference > Compiler-specific features > Function declaration keywords | |||
Several function declaration keywords tell the compiler to give a function special treatment. These function declaration keywords are not portable to other compilers.
__inlineThis instructs the compiler to compile C functions
inline. The semantics of __inline are exactly
the same as the C++ inline keyword:
__inline int f(int x) {return x*5+1:}
int f(int x, int y) {return f(x), f(y);}
The compiler always compiles functions inline when __inline is
used, except when debug_inlines is specified
(see Pragmas controlling debugging). Code
density and performance could be adversely affected if this keyword
is specified for large functions that are called from multiple places.
__irqThis enables a C or C++ function to be used as an interrupt routine. All registers, except floating-point registers, are preserved, not just those normally preserved under the APCS. Also, the function is exited by setting the pc to lr–4 and the PSR to its original value. This keyword is not available in tcc or tcpp.
Refer to Chapter 9 Handling
Processor Exceptions in the ARM Software Development Toolkit User Guide for
detailed information on using __irq.
__pureAsserts that a function declaration is pure.
Functions that are pure are candidates for common sub-expression elimination. By default, functions are assumed to be impure. That is, it is assumed that they have side-effects. This keyword tells the compiler that specific functions are candidates for common sub-expression elimination.
A function should only properly defined as pure if its result depends only on the value of its arguments and has no side effects. This means that it cannot use global variables, or dereference pointers, because the compiler assumes that the function does not access memory at all, except for the stack. When called twice with the same parameters, it must return the same value.
__swiA
SWI taking up to four integer-like arguments in registers r0 to r(argcount–1),
and returning up to four results in registers r0 to r(resultcount–1),
can be described by a function declaration. This causes function
invocations to be compiled inline as a SWI.
For a SWI returning 0 results use:
void __swi(swi_number)swi_name(int arg1,…, int argn);
For example:
void __swi(42) terminate_proc(int procnum);
For a SWI returning 1 result, use:
int __swi(swi_number)swi_name(int arg1,…, int argn);
For a SWI returning more than 1 result use:
struct { int res1,…,resn; }
__value_in_regs
__swi(swi_number) swi_name(int arg1,…,int argn);
The __value_in_regs qualifier is needed
to specify that a small non-packed structure of up to four words
(16 bytes) is returned in registers, rather than by the usual structure
passing mechanism defined in the ARM Procedure Call Standard.
Refer to Chapter 9 Handling Processor Exceptions in the ARM Software Development Toolkit User Guide for more information.
__swi_indirectAn indirect SWI that takes the number of the SWI to call as an argument in r12 can be described by a function declaration such as:
int __swi_indirect(ind_num) swi_name(intreal_num, intarg1, …argn);
where:
ind_numIs the SWI number used in the SWI instruction.
real_numIs the SWI number passed in r12 to the SWI handler. It can be specified at function call.
For example:
int __swi_indirect(0) ioctl(int swino, int fn, void *argp);
This can be called as:
ioctl(IOCTL+4, RESET, NULL);
It compiles to a SWI 0 with IOCTL+4 in r12.
Note that your system SWI handlers must support __swi_indirect.
__value_in_regsThis instructs the compiler to return a non-packed structure of up to four words in registers rather than using the stack. For example:
typedef struct int64_struct {
unsigned int lo;
unsigned int hi;
} int64;
__value_in_regs extern int64 mul64(unsigned a,
unsigned b);
Refer to the ARM Software Development Toolkit User Guide for information on the default method of passing and returning structures.
__weakIf any extern function or object declaration is weak, the linker does not fault an unresolved reference to the function or object. If the reference remains unresolved, its value is assumed to be zero.
If the reference is made from code that compiles to a Branch or Branch Link instruction, the reference is resolved as branching to itself. It is not possible to reference an unresolved weak symbol with a Branch or Branch Link instruction only. There must be a guard, such as:
__weak void f(void);
...
if(f) f();
___weak (three underscores) is a synonym
for __weak (two underscores).