Other Parts Discussed in Thread: MSP430F5418A
I found that dividing using /32 for unsigned operands is optimized into a shift by 5 (which is a good thing). Now using signed integers the optimization won't do this.
Following minimal example shows the issue:
#include "msp430f5418A.h"
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
volatile int u = -64;
volatile int a = u / 32;
volatile int b = u >> 5;
__bis_SR_register(LPM3_bits + GIE); // Enter LPM3, enable interrupts
__no_operation(); // For debugger
}
The relevant generated assembly is:
MOV.W #0xffc0,0x0000(SP)
MOV.W @SP,R12
MOV.W #0x0020,R13
CALLA #__divi
MOV.W R12,0x0002(SP)
MOV.W @SP,R15
RPT #5 RRAX.W R15
MOV.W R15,0x0004(SP)
The optimizations are turned to maximum (o4) and it's optimized for speed (opt_for_speed=5), building release code (no debug options selected).
Now I see there is a reason behind calling divi in this case - if something smaller than -32 is divided by 32 the result is 0 - which will not happen with a simple shift operation (result will be -1).
I was wondering however if a comparison of the numerator and divisor and after that either a return of 0 or returning the shifted value wouldn't be faster and smaller.
Something like this pseudocode:
if (abs(numerator) < divisor)
return 0;
else
return numerator >> log2(divisor);
I'm not used to writing algorithms in assembler - so my trying to do so will probably generate not a very nice result - that's why my statement is a bit vague and I ask the question here.