Fix powerpc-linux gcc.dg/20020103-1.c
Alan Modra
amodra@bigpond.net.au
Mon Nov 8 12:25:00 GMT 2004
This fixes 20020103-1.c with a minimal change. The results aren't quite
as good as the original patch I posted, with reload generating:
lwz 9,ext@got(30)
mr 3,9
instead of
lwz 3,ext@got(30)
Regression tested powerpc-linux.
* 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.
diff -urp -xCVS -x'*~' -x'.#*' gcc-virgin/gcc/config/rs6000/rs6000-protos.h gcc-current/gcc/config/rs6000/rs6000-protos.h
--- gcc-virgin/gcc/config/rs6000/rs6000-protos.h 2004-10-08 12:38:02.000000000 +0930
+++ gcc-current/gcc/config/rs6000/rs6000-protos.h 2004-11-08 11:10:27.154191049 +1030
@@ -204,6 +203,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);
extern int rs6000_hard_regno_nregs (int, enum machine_mode);
diff -urp -xCVS -x'*~' -x'.#*' gcc-virgin/gcc/config/rs6000/rs6000.c gcc-current/gcc/config/rs6000/rs6000.c
--- gcc-virgin/gcc/config/rs6000/rs6000.c 2004-11-08 09:25:07.333552703 +1030
+++ gcc-current/gcc/config/rs6000/rs6000.c 2004-11-08 11:10:28.202024670 +1030
@@ -900,7 +900,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
@@ -3695,6 +3695,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. */
@@ -4302,6 +4317,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)
@@ -4364,27 +4389,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
--
Alan Modra
IBM OzLabs - Linux Technology Centre
More information about the Gcc-patches
mailing list