This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Patch for offsettable_address_p to handle LO_SUM
- To: Michael Hayes <m dot hayes at elec dot canterbury dot ac dot nz>
- Subject: Re: Patch for offsettable_address_p to handle LO_SUM
- From: Jeffrey A Law <law at cygnus dot com>
- Date: Sun, 31 Jan 1999 15:34:36 -0700
- cc: egcs-patches at cygnus dot com
- Reply-To: law at cygnus dot com
In message <14003.50483.869516.12788@ongaonga.elec.canterbury.ac.nz>you write:
> This patch introduces a new function offsettable_lo_sum_address_p
> which returns non-zero if a LO_SUM memory reference is valid
> with an offset added to it.
I don't really see the need for a new function to do this. The test is
trivial enough.
> I doubt that this function will get called for most targets. The only
> one that should is the PA.
More correctly "will do anything useful" :-) The function could get called
for any target which allowed LO_SUM addresses in memrefs. Which is several.
> + @findex BITS_PER_LO_SUM
> + @item BITS_PER_LO_SUM
> + Number of bits loaded by a @code{LO_SUM} operation. This is used in
> + conjunction with @code{BITS_PER_HIGH} and @code{POINTER_SIZE} to
> + determine if a @code{LO_SUM} memory address is offsettable. If this is
> + undefined then a @code{LO_SUM} memory address is considered to be not
> + offsettable.
> +
> + @findex BITS_PER_HIGH
> + @item BITS_PER_HIGH
> + Number of bits loaded by a @code{HIGH} operation. This is used to determ
> ine
> + if a @code{LO_SUM} memory address is offsettable. If this is undefined
> + then a @code{LO_SUM} memory address is considered to be not offsettable.
> +
You might want to cross reference with the HIGH/LO_SUM stuff in rtl.texi.
> + #if defined (BITS_PER_LO_SUM) && defined (BITS_PER_HIGH)
> + #if BITS_PER_LO_SUM + BITS_PER_HIGH > POINTER_SIZE
> + #define PAGE_SIZE (1 << BITS_PER_LO_SUM)
> + #define PAGE_SEPARATION (1 << (POINTER_SIZE - BITS_PER_HIGH))
> + /* Here we have overlapping pages of size PAGE_SIZE, separated
> + by PAGE_SEPARATION (with most targets there is no overlap). When
> + dealing with memory addresses, we assume that the HIGH operation on
> + the address ADDR computes:
> + (ADDR + PAGE_SIZE / 2) & ~ (PAGE_SEPARATION - 1). Thus ADDR plus a
> + small offset is likely to fall within the same data page. The
> + maximum offset is plus or minus PAGE_SIZE / 2. However, due to
> + quantization of the high part, we have to be more conservative and
> + restrict the maximum offset to plus or minus (PAGE_SIZE -
> + PAGE_SEPARATION) / 2. */
> + #define LO_SUM_OFFSET_MAX ((PAGE_SIZE - PAGE_SEPARATION) / 2)
> + #else
> + #define LO_SUM_OFFSET_MAX 0
> + #endif /* BITS_PER_LO_SUM + BITS_PER_HIGH > POINTER_SIZE */
> + #else
> + /* By default, assume that a LO_SUM address is not offsettable. */
> + #define LO_SUM_OFFSET_MAX 0
> + #endif /* defined (BITS_PER_LO_SUM) && defined (BITS_PER_HIGH) */
> +
> +
> + /* Return 1 if OFFSET is valid for a LO_SUM memory address ADDR. */
> + int
> + offsettable_lo_sum_address_p (addr, offset)
> + rtx addr;
> + int offset;
> + {
> + if (GET_CODE (addr) != LO_SUM)
> + abort();
> +
> + return offset >= -LO_SUM_OFFSET_MAX && offset <= LO_SUM_OFFSET_MAX;
> + }
Is this really safe? Consider a (lo_sum (plus (symbol_ref) (LO_SUM_OFFSET_MAX))
We can't add anything to that since it'a already at the maximal offset.
Seems to me you have to peek inside the LO_SUM, add the constants, then look
at LO_SUM_MAX_OFFSET.
I also worry about the same problem at the other end. We could have a
(lo_sum (plus (symbol_ref) (-LO_SUM_OFFSET_MAX - 1))
That's not offsettable either.
I'm also a little concerned that someone would define those macros, but not be
aware of the assembler/linker issues for rounding HIGH. If we continue with
this code we probably should add a comment about this in the documentation.
Given that the PA port handles most of this kind of stuff early and doesn't
depend that much on offsettable memory references I wouldn't lose any sleep
if we just rejected LO_SUMs as not offsettable.
jeff