#11654 - tepples - Wed Oct 15, 2003 4:35 am
I wasn't sure whether to put this in the C++ section or the ASM section, but here goes:
One limitation of gcc version 3.2.2 (DevKit Advance R5 Beta 3) is that it does *not* like to LDMIA from memory to variables, even when LDMIA would be obviously the best answer. Instead, it generates successive LDR instructions, wasting cycles on address generation.
Test case: Compile this to assembly language with
arm-agb-elf-gcc -Wall -O3 -marm -mthumb-interwork -S ldmia.c -o ldmia.s
results in
Can't this
be replaced with this?
And how would I get GCC to generate LDMIA instructions without resorting to inline assembly language? I still can't get my head around how to specify pre- and post-conditions of inline assembly.
I've also had problems coaxing GCC into using register FP to hold a variable.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
One limitation of gcc version 3.2.2 (DevKit Advance R5 Beta 3) is that it does *not* like to LDMIA from memory to variables, even when LDMIA would be obviously the best answer. Instead, it generates successive LDR instructions, wasting cycles on address generation.
Test case: Compile this to assembly language with
arm-agb-elf-gcc -Wall -O3 -marm -mthumb-interwork -S ldmia.c -o ldmia.s
Code: |
/* ldmia_test() ************************** XORs successive pairs of ints in src, placing the result in dst. Reads 2*n ints (8*n bytes) from src and stores n ints (4*n bytes) to dst. */ void ldmia_test(unsigned int *dst, const unsigned int *src, unsigned int len) { /* force variables into ascending-ordered registers */ register unsigned int x; register unsigned int y asm("ip"); for(; len > 0; len--) { /* GCC *should* emit an LDMIA instruction that pulls in both x and y. */ x = *src++; y = *src++; *dst++ = x ^ y; } } |
results in
Code: |
.file "ldmia.c" .text .align 2 .global ldmia_test .type ldmia_test,function ldmia_test: @ Function supports interworking. @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. cmp r2, #0 @ lr needed for prologue bxeq lr .L6: ldr r3, [r1], #4 ldr ip, [r1], #4 subs r2, r2, #1 eor r3, r3, ip str r3, [r0], #4 bxeq lr b .L6 .Lfe1: .size ldmia_test,.Lfe1-ldmia_test .ident "GCC: (GNU) 3.2.2 (DevKit Advance R5 Beta 3)" |
Can't this
Code: |
ldr r3, [r1], #4 ldr ip, [r1], #4 |
be replaced with this?
Code: |
ldmia ip!, {r3, ip} |
And how would I get GCC to generate LDMIA instructions without resorting to inline assembly language? I still can't get my head around how to specify pre- and post-conditions of inline assembly.
I've also had problems coaxing GCC into using register FP to hold a variable.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.