First of all, this is not a tutorial of ARM assembler. For that, go here and
here. Instead the point is to present a simple hands-on example of how to add assembler instructions
within your C++ code to be compiled with gcc for the device binary. A good example project on Symbian/ARM assembler is
here.
Below is a example code snippet from
Nova3D the Open Source 3D Rendering Library for Symbian, released under the LGPL licence. It uses assembler to calculate (a * b) >> 16 where a and b are 16.16 bit fixed point numbers.
/**
* Multiplies two fixed point integers and shifts away the
* extra precision.
*/
inline TInt FixedLargeMul( TInt aMultiplicand, TInt aMultiplier )
{
#ifdef __WINS__
//=============================================
// EMULATOR CODE: use TInt64
//=============================================
TInt64 coeff1_64( aMultiplicand );
TInt64 coeff2_64( aMultiplier );
coeff1_64 *= coeff2_64;
coeff1_64 >>= 16;
return coeff1_64.Low();
#else
//=============================================
// DEVICE CODE: use native 32x32->64 multiply
//=============================================
TInt ret;
// multiply the values -> r6:r7
asm volatile ( "SMULL r6, r7, %0, %1" : :
"r"(aMultiplicand), "r"(aMultiplier) : "r6", "r7" );
// shift away the lowest 16 bits of result precision
asm volatile ( "MOV r6, r6, LSR #16" : : : "r6" );
// or the halfwords together
asm volatile ( "ORR r6, r6, r7, LSL #16" : : : "r6" );
// store in memory for return
asm volatile ( "STR r6, %0" : "=m"(ret) );
return ret;
#endif
}
The volatile keyword is important; it keeps the compiler from optimizing away instructions it deems unnecessary. So, this is the gcc asm syntax:
asm ( "instructions" : outputs : inputs : clobbered-regs );
The "outputs"/"inputs" are basically memory addresses (variables). If you dont need or want to know the specifics, just always use "=m"(variableName) for outputs and "m"(variableName) for inputs. If you do, look
here. The "clobbered regs" are registers that get modified by the instructions. Oh, and one thing about the instruction set available that was, at least to me, quite unclear at first: the (Nokia) phones’ CPU, ARM9, does *not* include the instruction sets of ARM 5E/6, rather than merely ARMv4t as it is not based on those processor cores.
Now go optimize.
— matti
|