------- Comment #2 from Eric dot Doenges at betty-tv dot com  2006-04-04 09:13 
-------
(In reply to comment #1)
> This code is undefined:
>   len = ((unsigned int)&_ram_erase_sector_end 
>          - (unsigned int)&_ram_erase_sector_start) / sizeof(unsigned int);
> 
> That is obviously undefined as taking the difference between two pointers 
> which
> are not in the same array is undefined code.
> 
> Even the comparision:
> p_rom < p_end;
> is undefined.
> 
In the code I took this snippet from, _ram_erase_sector_start and
_ram_erase_sector_end are symbols
generated by the linker at the start and the end of a special segment which I
need to copy to ram,
so I would argue that these pointers do in fact refer to the same "array" (in
this case, the "array" is the
entire flash memory). 

However, none of this should affect the decision to use (or not to use) the
post-indexed addressing
mode. If I replace the for loop with a for (len = 100; len > 0; --len), the
quality of the generated code
actually degrades even further:

        ldr     r2, .L7
        ldr     r1, .L7+4
        @ lr needed for prologue
.L2:
        ldr     r3, [r1, #-4]
        str     r3, [r2, #-4]
        ldr     r3, .L7+8
        add     r2, r2, #4
        cmp     r2, r3
        add     r1, r1, #4
        bne     .L2
        bx      lr

While I thinks it's nifty that gcc recognizes that it doesn't need to keep the
len variable, but instead
uses p_ram to determine when the loop is finished, I also think it's pretty
brain-dead that it won't
use post-indexed addressing for either the ldr or str in the loop. And why it
thinks it needs to load
the constant end address to compare against every time inside the loop instead
of once into a scratch
register outside the loop is anyone's guess.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27016

Reply via email to