This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Compiler doesn't implement "Conditional Execution Instruction" (e.g. SUBS). Why ?

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

Parents
  • 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.

Reply
  • 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.

Children