ARM > Efficient C for ARM > Function Argument Types
Example
For the above example, ARMCC generates:
addshorts1
ADD r0,r0,r1,ASR #1 ; r0 = (int)a + ((int)b>>1)
MOV r0,r0,LSL #16
MOV r0,r0,ASR #16 ; r0 = (short)r0
MOV pc,r14 ; return r0
It assumes input values are in the correct range.
GCC generates:
addshorts1
MOV r0,r0,LSL #16
MOV r1,r1,LSL #16
MOV r1,r1,ASR #17 ; r1 = (int)a
ADD r1,r1,r0,ASR #16 ; r1 += (int)b
MOV r1,r1,LSL #16
MOV r0,r1,ASR #16 ; r0 = (short)r1
MOV pc,lr ; return r0
It makes no assumptions about the range of argument values so sign extends the values on entry.
Remarks
This is from ARM System Developer’s Guide section 5.2.2.
- This sort of behaviour differs from toolchain to toolchain.
- It makes it hard to mix objects reliably between compilers.
The LSL #16
+ ASR #16
is a sign extending operation.
ARMCC passes narrow arguments and return value. GCC passes wide but returns narrow.
You can see from this that simply mixing objects between different compilers can cause all sorts of problems.