I am in the process of trying to figure out how many cycles some uint32 operations will take on a 16bit dsPIC. I started with bitwise AND and wrote the following program:
int main(void) {
unsigned long var1, var2, var3;
var1 = 80000ul;
var2 = 190000ul;
while (1) {
var3 = var1 & var2;
}
var1 = 0;
return 0;
}
Looking at the disassembly to see what the compiler came up with for the assembly I got the following:
! var3 = var1 & var2;
0x2DE: MOV [W14+4], W0
0x2E0: MOV [W14+6], W1
0x2E2: MOV.D [W14], W2
0x2E4: MOV W2, W4
0x2E6: MOV W3, W2
0x2E8: MOV W0, W3
0x2EA: MOV W1, W0
0x2EC: AND W4, W3, W4
0x2EE: AND W2, W0, W0
0x2F0: CLR W1
0x2F2: SL W0, #0, W1
0x2F4: MOV #0x0, W0
0x2F6: MOV.D W0, W2
0x2F8: MUL.UU W4, #1, W0
0x2FA: IOR W2, W0, W2
0x2FC: IOR W3, W1, W3
0x2FE: MOV W2, [W14+8]
0x300: MOV W3, [W14+10]
20 cycles, 6 I/O moves and 14 core. This looks bonkers to me. Couldn't it just do this?
MOV.D [W14+4], W0
MOV.D [W14], W2
AND W0, W2, W0
AND W1, W3, W1
MOV.D W0, [W14+8]
That drops core cycles to 2 for the core which makes logical sense to me at least (2 16-bit-wide AND's). What is the compiler up to that I don't understand?