This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

i960 argument pointer


There are some cleanups to CSE that I'd like to make, some of which
will help x86 TLS code generation.  One thing standing in the way of
that is a strange feature of the i960 argument pointer.  I attach
two messages Jim Wilson sent to me that describe the situation quite
clearly.

I still havn't decided if I'll put the CSE change into mainline or
b-i-b (depends on whether I can find a bug fixed by it as well  ;-),
but I think the cleanup for i960 might as well go into mainline.
Certainly it makes the situation less confusing.

Causes no new regressions testing i960-coff.


r~
--- Begin Message ---
The i960 has a dedicated arg pointer register.  The ABI allows you to either
pass arguments in registers, or set the arg pointer reg to point at them.  In
practice, the only time the arg pointer register is ever used is for stdarg
functions, since it is easier to put them in a block of memory and store that
address in the arg pointer register than to try to pass them in registers.

The i960 has no register architected to hold zero.  However, it is convenient
to have one, it being rather RISC like.  Since the arg pointer is rarely used,
the ABI declares that the arg pointer register either holds an arg pointer, or
the value zero.  The i960 port takes advantage of this to optimize code in
non-stdarg functions.  If you look at the i960.md file, you will see patterns
that test current_function_args_size and a few other variables to see if we
have a zero-value register or not.  This is used for zero-stores to memory,
since there is no instruction for storing constants to memory, and storing
zero to memory is a rather common operation.

These conventions cause a problem in cse because it assumes that the arg
pointer is always used for arg pointer values.  This assumption is not
true for i960.

I recall that the convex port also had funny arg pointer register conventions,
but that port has been deleted, so it probably doesn't matter anymore.

Perhaps the i960 problem can be fixed by defining a fake arg pointer register
that gets eliminated into the real arg pointer register by reload.  Then it
should be true that the fake arg pointer register is always non-zero.

It might be reasonable to solve the problem by getting rid of the i960 port.
It has been broken for about a year and half, and the only people who ever
notice are people who try to build every target.  Note the broken "return"
pattern.  I stared to fix this last summer, and then decided I didn't care
enough.  Also, there is no i960-elf support in gcc.  A target has to be mostly
dead not to have any elf support.  Also, gdb obsoleted the i960 port 10 days
ago for lack of a maintainer.  It will be removed in the next gdb release if
no one rescues it.

I added the patch May 5 1992.  My gcc2 message on that day says
"I added support for the Intel 80960 (i960) processor to the gcc2 sources
today."
        http://cygweb.sfbay.redhat.com/majordomo-archive/gcc2-archive/gcc2.9205
This was probably discussed in private mail with Richard Kenner when submitted
to the FSF, and it was probably written before we kept mail archives, or used
source control, so further details are not available.

Jim
--- End Message ---
--- Begin Message ---
I think the problem is in i960_setup_incoming_varargs.  One of the first
things it does is compare the arg pointer against zero to determine if the
caller passed in an argblock.  If there is one, then we use it.  If not, then
we have to create one.  If cse assumes that the arg pointer is never zero,
then it would incorrectly optimize away this code.  Distinguishing between
the physical and virtual arg pointer registers might solve this.

This relates to MAYBE_REG_PARM_STACK_SPACE.  The i960 calling convention is
that if we are passing all arguments in register, we don't allocate stack space
for them.  However, if one or more arguments gets passed on the stack, then we
do create stack space for all of the register arguments.  This is different
from how most all other ABIs work, since they either always or never create
stack space for arguments in register.  The i960 creates stack space maybe
depending on the size of the arguments.  Functions with fixed arguments know
based on the size of the arguments whether the stack space was allocated.
But stdarg functions don't know the size of the arguments.  Thus in
i960_setup_incoming_varargs we have to check to see whether the stack space
was already allocated or not.

Gcc always creates the stack space in the same place, at the bottom of the
caller's frame, so perhaps there is some tricky way to optimize this.  However,
the ABI does not require this.  The ABI allows the argblock to be allocated
anyplace in memory.  Thus, we may be incompatible with other i960 compilers
or hand-written i960 code if we make assumptions about where the argblock is.
I don't know if anyone actually takes advantage of this ABI wierdness though.

Last time I checked, the i960 port was mostly working if the broken "return"
pattern was disabled.  The second next major thing that is broken would be
C++ EH.

Jim
--- End Message ---

Attachment: z
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]