Hello,
In the excellent textbook ARM System Developer's Guide: Designing and Optimizing System Software (Andrew N. Sloss, Dominic Symes, Chris Wright - Elsevier, 2004) there is example on the page 115:
int checksum_v6(int *data) { unsigned int i; int sum=0; for (i=64; i!=0; i--) { sum += *(data++); } return sum; }
that is disassembled (according to authors) in the following code:
checksum_v6
MOV r2,r0 ; r2 = data
MOV r0,#0 ; sum = 0
MOV r1,#0x40 ; i = 64
checksum_v6_loop
LDR r3,[r2],#4 ; r3 = *(data++)
SUBS r1,r1,#1 ; i-- and set flags
ADD r0,r3,r0 ; sum += r3
BNE checksum_v6_loop ; if (i!=0) goto loop
MOV pc,r14 ; return sum
I reproduced this example, and what I've got this:
checksum_v6 PROC
MOV r2,r0
MOV r0,#0
MOV r1,#0x40
|L1.48|
LDR r3,[r2],#4
ADD r0,r0,r3
SUB r1,r1,#1
CMP r1,#0
BNE |L1.48|
BX lr
ENDP
As you can state (highlighted in red) in my version of disassembly instead of one conditional execution instruction (that is more efficient) compiler placed 2 instructions: SUB and CMP.
I've tried with all optimization options but couldn't reproduce book authors disassembly.
Does exist some flag that regulates such kind of things ?
Thanks in advance.
Pavel
Pavel,
As you have discovered, there is no mandated mapping from "C" code to assembly code; the compiler is free to produce anything which has equivalent behaviour, and may produce some initially unintuitive results based on its understanding of the issuing capabilities / resources of the CPU it is targeting.
Compiling with a recent ARMCC 5 using "armcc -O3 -Ospace --cpu=cortex-a7 -S" does produce the SUBS you are looking for, though again does not precisely match what was observed by the authors using the tool versions they had at the time, and the settings they used:
checksum_v6 PROC MOV r2,r0 MOV r0,#0 MOV r1,#0x40 |L0.12| SUBS r1,r1,#1 LDR r3,[r2],#4 ADD r0,r0,r3 BNE |L0.12| BX lr ENDP
Best regards
Simon.
Thanks Simon,
Indeed, with these options (I specified first 3 flags ignoring what signifies "-S" flag) the code is compiled according to textbook (i.e. with SUBS)
Then I experimented a little bit, i.e. tried with other values for concerned flags.
According to my exercises, only optimization level (-O3) is relevant to introducing conditional instructions: if I leave -cpu empty and optimization goal (speed or space) default, the code is compiled with SUBS.
Before posting this thread, it seems I also experienced with optimization level, but didn't get SUBS.
Strange ...
Thanks once more.
Best Regards