Hi,
this fixes reload failures in 64-bit mode with -mcmodel=medium for targets
that define ASM_OUTPUT_SPECIAL_POOL_ENTRY_P to 0; that's the case for the
VxWorks port we'll submit because of the compatibility with the system linker,
which rejects .got sections in object files.
When reload ends up calling rs6000_emit_move on a register on the LHS and
(const (symbol_ref) (const_int)) on the RHS, the function invokes:
operands[1] = force_const_mem (mode, operands[1]);
creating (mem (symbol_ref)), which then needs to be legitimized on TARGET_TOC
targets. That's done by the immediately following block:
if (TARGET_TOC
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
&& constant_pool_expr_p (XEXP (operands[1], 0))
&& ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
get_pool_constant (XEXP (operands[1], 0)),
get_pool_mode (XEXP (operands[1], 0))))
{
rtx tocref = create_TOC_reference (XEXP (operands[1], 0),
operands[0]);
operands[1] = gen_const_mem (mode, tocref);
set_mem_alias_set (operands[1], get_TOC_alias_set ());
}
on most targets, but is disabled if ASM_OUTPUT_SPECIAL_POOL_ENTRY_P is 0.
Now you don't need to have a special pool to call create_TOC_reference, you
can call it for regular TOC references as well, as done a few lines above:
/* If this is a SYMBOL_REF that refers to a constant pool entry,
and we have put it in the TOC, we just need to make a TOC-relative
reference to it. */
if (TARGET_TOC
&& GET_CODE (operands[1]) == SYMBOL_REF
&& use_toc_relative_ref (operands[1], mode))
operands[1] = create_TOC_reference (operands[1], operands[0]);
So the attached patch does it there too.
Tested on PowerPC64/Linux (LRA) and VxWorks (reload), OK for the mainline?
2016-10-08 Eric Botcazou <ebotca...@adacore.com>
* config/rs6000/rs6000.c (rs6000_emit_move): Also use a TOC reference
after forcing to constant memory when the code model is medium.
--
Eric Botcazou
Index: config/rs6000/rs6000.c
===================================================================
--- config/rs6000/rs6000.c (revision 240888)
+++ config/rs6000/rs6000.c (working copy)
@@ -10590,10 +10590,7 @@ rs6000_emit_move (rtx dest, rtx source,
if (TARGET_TOC
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
- && constant_pool_expr_p (XEXP (operands[1], 0))
- && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
- get_pool_constant (XEXP (operands[1], 0)),
- get_pool_mode (XEXP (operands[1], 0))))
+ && use_toc_relative_ref (XEXP (operands[1], 0), Pmode))
{
rtx tocref = create_TOC_reference (XEXP (operands[1], 0),
operands[0]);