3.1.2. 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.

__inline

This 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.

__irq

This 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.

__pure

Asserts 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.

__swi

A 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_indirect

An 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(int real_num, 
				 int arg1, … argn);

where:

ind_num

Is the SWI number used in the SWI instruction.

real_num

Is 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_regs

This 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.

__weak

If 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).

Copyright © 1997, 1998 ARM Limited. All rights reserved.ARM DUI 0041C