expanding addrs for initializers

DJ Delorie dj@redhat.com
Wed Aug 31 14:27:00 GMT 2005


> X-Sieve: CMU Sieve 2.2
> From: Richard Sandiford <richard@codesourcery.com>
> Mail-Followup-To: DJ Delorie <dj@redhat.com>,rth@redhat.com,  gcc-patches@gcc.gnu.org, richard@codesourcery.com
> Cc: rth@redhat.com, gcc-patches@gcc.gnu.org
> Date: Wed, 31 Aug 2005 10:54:58 +0100
> X-RedHat-Spam-Score: 0 
> 
> DJ Delorie <dj@redhat.com> writes:
> > FYI I can reproduce this with mips-elf too.
> >
> > $ ./cc1 -quiet dj.c
> > dj.c:3: error: initializer element is not constant
> >
> > dj@greed pts/0 ~/gnu/gcc/mips-elf/gcc
> > $ cat dj.c
> > extern void reset();
> >
> > long long j = (long long)&reset;
> 
> I might be missing the point, but the error is correct for o32.

The point is twofold:

1. MIPS is going through the same logic that produces an *invalid*
   initializer for other chips, even considering the lack of support.

2. The M32C *does* have full support for this in the chip, but gcc
   doesn't.

Imagine, if you will, a MIPS chip with 64 bit address space but 32 bit
registers.  Most of the time, 32 bit pointers are ideal.  Sometimes
you need the full 64 bit address of something, such as a reset vector
(which is the specific case I need the m32c fix for).  GCC has no way
of initializing a 64 bit variable with the 64 bit address of
something, when pointers don't default to 64 bits, even if the
assembler and linker support it.  It's not a question of whether the
target supports it or not; gcc sees a conversion that looks like
address->int->long and says "I can't do that".  Of course it can't,
but the target and/or assembler might be able to, because they know
if/how addresses get extended or at least referred to in an extended
form.

The actual code I'm trying to make work for m32c looks something like
this:

  void my_reset(void);
  long reset_vector __attribute__((section(".resetvec"))) = (long)&my_reset;

The assembler and linker support this fully.  The chip has the address
space and relocs for this, even though the default pointer size is 16
bits (GPRs are 16 bits).  I can't get gcc to support it.

Consider the i386's 16-bit "medium model".  All the data fits inside
one 64k segment, and pointers are 16 bits.  But functions live
elsewhere in the 1mb address map, and *function* pointers are bigger.

The xstormy16 chip is similar too.  For xstormy16 and m32c, if you
have a 16 bit reloc for a function outside the 64k address space, a
code stub is created by the linker inside the 64k code space, which
just jumps to the real 32-bit address.  This works for everything
*except* reset vectors.



More information about the Gcc-patches mailing list