This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Fix powerpc-linux gcc.dg/20020103-1.c
On Mon, Nov 08, 2004 at 10:01:33PM +1030, Alan Modra wrote:
> This fixes 20020103-1.c with a minimal change.
The same for gcc-3.4. Requires backport of another mainline fix.
* config/rs6000/rs6000.c (rs6000_cannot_force_const_mem): New function.
(TARGET_CANNOT_FORCE_CONST_MEM): Update.
(rs6000_emit_move): Simplify code handling small data. Handle
got_operand earlier, before reload_in_progress tests.
* config/rs6000/rs6000-protos.h (rs6000_cannot_force_const_mem):
Declare.
2003-11-27 Richard Sandiford <rsandifo@redhat.com>
* reload.c (CONST_POOL_OK_P): New macro.
(find_reloads): Use it to decide whether a constant can be forced
into memory.
diff -urp -xCVS -x'*~' -x'.#*' gcc-3.4-virgin/gcc/config/rs6000/rs6000-protos.h gcc-3.4-got/gcc/config/rs6000/rs6000-protos.h
--- gcc-3.4-virgin/gcc/config/rs6000/rs6000-protos.h 2004-08-03 11:57:50.000000000 +0930
+++ gcc-3.4-got/gcc/config/rs6000/rs6000-protos.h 2004-11-10 10:46:50.055723987 +1030
@@ -199,6 +199,7 @@ extern int rs6000_register_move_cost (en
enum reg_class, enum reg_class);
extern int rs6000_memory_move_cost (enum machine_mode, enum reg_class, int);
extern bool rs6000_tls_referenced_p (rtx);
+extern bool rs6000_cannot_force_const_mem (rtx);
extern int rs6000_tls_symbol_ref (rtx, enum machine_mode);
extern void rs6000_output_dwarf_dtprel (FILE*, int, rtx);
diff -urp -xCVS -x'*~' -x'.#*' gcc-3.4-virgin/gcc/config/rs6000/rs6000.c gcc-3.4-got/gcc/config/rs6000/rs6000.c
--- gcc-3.4-virgin/gcc/config/rs6000/rs6000.c 2004-10-23 19:26:49.000000000 +0930
+++ gcc-3.4-got/gcc/config/rs6000/rs6000.c 2004-11-10 10:46:50.087718942 +1030
@@ -548,7 +548,7 @@ static const char alt_reg_names[][8] =
#define TARGET_HAVE_TLS HAVE_AS_TLS
#undef TARGET_CANNOT_FORCE_CONST_MEM
-#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
+#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem
#undef TARGET_ASM_FUNCTION_PROLOGUE
#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
@@ -3142,6 +3142,21 @@ rs6000_tls_referenced_p (rtx x)
return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
}
+/* Return 1 if X is a V4 got reference or if it contains a thread-local
+ symbol. */
+
+bool
+rs6000_cannot_force_const_mem (rtx x)
+{
+ if (DEFAULT_ABI == ABI_V4
+ && flag_pic == 1
+ && GET_MODE (x) == SImode
+ && got_operand (x, GET_MODE (x)))
+ return true;
+
+ return rs6000_tls_referenced_p (x);
+}
+
/* Return 1 if *X is a thread-local symbol. This is the same as
rs6000_tls_symbol_ref except for the type of the unused argument. */
@@ -3630,6 +3645,16 @@ rs6000_emit_move (rtx dest, rtx source,
operands[1] = rs6000_legitimize_tls_address (operands[1], model);
}
+ /* Recognize V4 got references. */
+ if (DEFAULT_ABI == ABI_V4
+ && flag_pic == 1
+ && mode == SImode
+ && got_operand (operands[1], mode))
+ {
+ emit_insn (gen_movsi_got (operands[0], operands[1]));
+ return;
+ }
+
/* Handle the case where reload calls us with an invalid address. */
if (reload_in_progress && mode == Pmode
&& (! general_operand (operands[1], mode)
@@ -3693,27 +3718,15 @@ rs6000_emit_move (rtx dest, rtx source,
break;
case SImode:
- case DImode:
/* Use default pattern for address of ELF small data */
- if (TARGET_ELF
- && mode == Pmode
- && DEFAULT_ABI == ABI_V4
+ if (DEFAULT_ABI == ABI_V4
&& (GET_CODE (operands[1]) == SYMBOL_REF
|| GET_CODE (operands[1]) == CONST)
&& small_data_operand (operands[1], mode))
- {
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
- return;
- }
-
- if (DEFAULT_ABI == ABI_V4
- && mode == Pmode && mode == SImode
- && flag_pic == 1 && got_operand (operands[1], mode))
- {
- emit_insn (gen_movsi_got (operands[0], operands[1]));
- return;
- }
+ goto emit_set;
+ /* Fall thru */
+ case DImode:
if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
&& TARGET_NO_TOC
&& ! flag_pic
diff -urp -xCVS -x'*~' -x'.#*' gcc-3.4-virgin/gcc/reload.c gcc-3.4-got/gcc/reload.c
--- gcc-3.4-virgin/gcc/reload.c 2004-09-15 09:17:28.000000000 +0930
+++ gcc-3.4-got/gcc/reload.c 2004-11-10 10:46:50.093717996 +1030
@@ -105,6 +105,13 @@ a register with any other reload. */
#include "function.h"
#include "toplev.h"
#include "params.h"
+#include "target.h"
+
+/* True if X is a constant that can be forced into the constant pool. */
+#define CONST_POOL_OK_P(X) \
+ (CONSTANT_P (X) \
+ && GET_CODE (X) != HIGH \
+ && !targetm.cannot_force_const_mem (X))
#ifndef REGNO_MODE_OK_FOR_BASE_P
#define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) REGNO_OK_FOR_BASE_P (REGNO)
@@ -3129,9 +3136,7 @@ find_reloads (rtx insn, int replace, int
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
&& reg_renumber[REGNO (operand)] < 0))
win = 1;
- if (CONSTANT_P (operand)
- /* force_const_mem does not accept HIGH. */
- && GET_CODE (operand) != HIGH)
+ if (CONST_POOL_OK_P (operand))
badop = 0;
constmemok = 1;
break;
@@ -3193,8 +3198,7 @@ find_reloads (rtx insn, int replace, int
&& offsettable_memref_p (reg_equiv_mem[REGNO (operand)]))
|| (reg_equiv_address[REGNO (operand)] != 0))))
win = 1;
- /* force_const_mem does not accept HIGH. */
- if ((CONSTANT_P (operand) && GET_CODE (operand) != HIGH)
+ if (CONST_POOL_OK_P (operand)
|| GET_CODE (operand) == MEM)
badop = 0;
constmemok = 1;
@@ -3314,7 +3318,7 @@ find_reloads (rtx insn, int replace, int
/* If we didn't already win, we can reload
constants via force_const_mem, and other
MEMs by reloading the address like for 'o'. */
- if ((CONSTANT_P (operand) && GET_CODE (operand) != HIGH)
+ if (CONST_POOL_OK_P (operand)
|| GET_CODE (operand) == MEM)
badop = 0;
constmemok = 1;
@@ -3390,9 +3394,7 @@ find_reloads (rtx insn, int replace, int
an early reload pass. Note that the test here is
precisely the same as in the code below that calls
force_const_mem. */
- if (CONSTANT_P (operand)
- /* force_const_mem does not accept HIGH. */
- && GET_CODE (operand) != HIGH
+ if (CONST_POOL_OK_P (operand)
&& ((PREFERRED_RELOAD_CLASS (operand,
(enum reg_class) this_alternative[i])
== NO_REGS)
@@ -3772,9 +3774,7 @@ find_reloads (rtx insn, int replace, int
into registers are here changed into memory references. */
for (i = 0; i < noperands; i++)
if (! goal_alternative_win[i]
- && CONSTANT_P (recog_data.operand[i])
- /* force_const_mem does not accept HIGH. */
- && GET_CODE (recog_data.operand[i]) != HIGH
+ && CONST_POOL_OK_P (recog_data.operand[i])
&& ((PREFERRED_RELOAD_CLASS (recog_data.operand[i],
(enum reg_class) goal_alternative[i])
== NO_REGS)
--
Alan Modra
IBM OzLabs - Linux Technology Centre