This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: modifying the ARM generation behavior?
- To: Josh Fryman <fryman at cc dot gatech dot edu>
- Subject: Re: modifying the ARM generation behavior?
- From: Nick Clifton <nickc at cambridge dot redhat dot com>
- Date: 24 Sep 2001 11:42:34 +0100
- Cc: gcc at gcc dot gnu dot org
- References: <3BACBCB7.5B8AF1A@cc.gatech.edu>
Hi Josh,
> in C
> ----
> void foo( void )
> {
> int myvar=42;
> printf("myvar=%d\n",myvar);
> }
>
> in ARM-ASM (edited to make shorter)
> ----------
> .section .rodata
> .LC0:
> .ascii "myvar=%d\012\000"
> .text
> foo:
> .....
> ldr r0, .L4
> ldr r1, [fp, #-16]
> bl printf
> b .L3
> .L4:
> .word .LC0
> .word myvar
> .L3:
> ldmea fp, {fp, sp, pc}
>
> note how gcc has "stuck" into the middle of the instruction stream
> some data values at .L4.
This is a little unfair. GCC will normally put these contants at the
end of the function, not in the middle of the instruction stream.
With the current CVS sources for example, your test case compiles as:
....
ldr r0, .L2
mov r1, #42
ldr lr, [sp], #4
b printf
.L2:
.word .LC0
(This is with -O3 and -fomit-frame-pointer, so the redundant variable
myvar has been eliminated and the call to printf has been turned into
a tailcall). Even at -O0 the constants are still dumped at the end of
the function and the branch to .L3 is eliminated. It it true of
course, that if the function is very big then the constant pool may
have to be dumped inside it, and branches a round the pool generated,
but this is rare occurrence.
> it would make my life much easier (for research purposes) if i could
> move these little random scattered data segments into the main data
> segment or an alternate data segment...
I am intrigued - how would this help your research ? Are you
investigating ARMs with Harvard architectures ?
> with a few registers already pinned for other uses, like lr, sp, etc,
> i'd like to reserve "another" register for being a pointer to a
> special data segment of these values - say r11.
r11 is already in use. It is the frame pointer. In fact the ARM is
rather short of "free registers". r9 to r15 have already been
assigned. r0 - r3 are the argument registers which only leaves r4 -
r8. The ARM ABI document (the ATPCS) specifies these as variable
registers, so reserving one as a global register would contravene the
specification. This is not necessarily a huge problem, but you should
be aware of the fact. It will also mean that you will need to make
sure that you mark the binaries with this feature so that they can be
distinguished from "ordinary" binaries. (You may also be interested
to know that the next generation of the ARM ABI is being developed.
See http://www.armdevzone.com/ for more information).
> then, at the very beginning of the program, r11 gets loaded with a
> pointer to the data segment containing all these address offsets,
> and we no longer have to mix data into the instruction stream.
What happens if there is too much data to fit into the area pointed to
by r11 ? (or whichever register is used). Since this may only be
discovered at link time, it is too late to recompile the objects to
use the old system...
What about shared libraries ? Would r11 be loaded with a different
value whenever a shared library function is called, or would the
share'd libraries data have to merged into the application's own data?
Just some things to think about... :-)
Cheers
Nick