I'm interested, why for Cortex M3 microcontroller (stm32f103) compiler sometimes generates a NOP instruction after branch. And why it sometimes doesn't.
For example:
0x08000496 2400 MOVS r4,#0x00
0x08000498 4625 MOV r5,r4
0x0800049A E006 B 0x080004AA
64: res=res+a[i];
65: }
0x0800049C F85A0034 LDR r0,[r10,r4,LSL #3] // No NOP after B
0x080004A0 EB100808 ADDS r8,r0,r8
0x080004A4 1C64 ADDS r4,r4,#1
0x080004A6 F1450500 ADC r5,r5,#0x00
0x080004AA 1BA0 SUBS r0,r4,r6
0x080004AC EB750007 SBCS r0,r5,r7
0x080004B0 DBF4 BLT 0x0800049C
66: int64_t avg=res/x;
0x080004B2 BF00 NOP // <------------------- NOP after BLT
69: int v=countbits1(5);
0x080004B4 2005 MOVS r0,#0x05
0x080004B6 F7FFFFA2 BL.W countbits1 (0x080003FE)
0x080004BA 9001 STR r0,[sp,#0x04] // No NOP after BL.W
72: unsigned int b=countLeadingZeros(5);
73:
0x080004BC 2005 MOVS r0,#0x05
My initial guess was that long instruction needs word-alignment but BL.W after NOP actually doesn't have it.
If this NOP is related to pipeline somehow than why there are branches without nop's after them?
I'm confused.
UPDATE:
It turns out that branch may be not relevant at all. I tried to moving declaration of unused local variable int64_t avg – and NOP moved along with it.
So I beleive pjc50 comment is right and this NOP is there just to let debugger put a breakpoint on this line.
Best Answer
Try moving the int64_t line of C up or down a bit. The first two are clearly part of a for loop; but line 66 has generated no code at all. My guess is that the NOP is for the benefit of the debugger so that every line of C generates at least one instruction.
(Not all debuggers do this on all platforms; Visual Studio will simply move your breakpoint to the nearest line that has code associated with it.)