This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: mips tls with -mlong64/-mgp32
DJ Delorie <dj@redhat.com> writes:
> +/* Returns true if OFFSET is within the range [0, ALIGN), where ALIGN
> + is the alignment (in bytes) of SYMBOL_REF X. */
(thanks for adding the "(in bytes)" btw.)
> +static bool
> +mips_offset_within_alignment_p (rtx x, HOST_WIDE_INT offset)
> +{
> + /* If for some reason we can't get the alignment for the
> + symbol, initializing this to zero means we won't accept any
> + offset. */
> + HOST_WIDE_INT align = 0;
I suppose with the way I've speced the function, this ought to be:
/* If for some reason we can't get the alignment for the
symbol, initializing this to one means we'll only accept
a zero offset. */
HOST_WIDE_INT align = 1;
> + tree t;
> +
> + /* Get the alignment of the symbol we're referring to. */
> + t = SYMBOL_REF_DECL (x);
> + if (t)
> + align = DECL_ALIGN_UNIT (t);
> +
> + if (offset < align)
> + return true;
> + return false;
This should check for negative offsets too. Just change the last
three statements to:
return offset >= 0 && offset < align;
> @@ -1413,20 +1439,26 @@ mips_symbolic_constant_p (rtx x, enum mi
> address, and we will apply a 16-bit offset after loading it.
> If the symbol is local, the linker should provide enough local
> GOT entries for a 16-bit offset, but larger offsets may lead
> to GOT overflow. */
> return SMALL_INT (offset);
>
> + case SYMBOL_TPREL:
> + case SYMBOL_DTPREL:
> + /* There is no carry between the HI and LO REL relocations, so the
> + offset is only valid if we know it won't lead to such a carry. */
> + if (mips_offset_within_alignment_p (x, INTVAL (offset)))
> + return true;
> + /* Fall through. */
> +
> case SYMBOL_GOT_DISP:
> case SYMBOL_GOTOFF_DISP:
> case SYMBOL_GOTOFF_CALL:
> case SYMBOL_GOTOFF_LOADGP:
> case SYMBOL_TLSGD:
> case SYMBOL_TLSLDM:
> - case SYMBOL_DTPREL:
> - case SYMBOL_TPREL:
> case SYMBOL_GOTTPREL:
> case SYMBOL_TLS:
> case SYMBOL_HALF:
> return false;
> }
> gcc_unreachable ();
This isn't right, you fall through a gcc_unreachable ().
Just change it to:
/* There is no carry between the HI and LO REL relocations, so the
offset is only valid if we know it won't lead to such a carry. */
return mips_offset_within_alignment_p (x, INTVAL (offset));
OK with those changes, if it survives testing.
Thanks,
Richard