From: David Edelsohn Date: Tue, 26 Nov 2002 15:59:58 +0000 (+0000) Subject: re PR middle-end/8362 (hard reg not substituted for all pseudos on PowerPC) X-Git-Tag: releases/gcc-3.2.2~247 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fe4cded8aa9bd2c8afc8173fe6c26d008ebead06;p=thirdparty%2Fgcc.git re PR middle-end/8362 (hard reg not substituted for all pseudos on PowerPC) * config/rs6000/rs6000.c (rs6000_flag_pic): New variable. (rs6000_override_options): Save original flag_pic value. (rs6000_encode_section_info): More accurate test for "local" symbol. PR 8362 * config/rs6000/rs6000.c (rs6000_outout_load_multiple): New function. * config/rs6000/rs6000.md (ldmsi[3-8]): New patterns. From-SVN: r59520 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cbbf7262d44a..04122275c2bf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2002-11-26 David Edelsohn + + * config/rs6000/rs6000.c (rs6000_flag_pic): New variable. + (rs6000_override_options): Save original flag_pic value. + (rs6000_encode_section_info): More accurate test for "local" symbol. + + PR 8362 + * config/rs6000/rs6000.c (rs6000_outout_load_multiple): New function. + * config/rs6000/rs6000.md (ldmsi[3-8]): New patterns. + 2002-11-25 Christian Ehrhardt PR c/8639 diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 19aeb07b9e0c..f6024ec1edf8 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -77,6 +77,7 @@ extern int constant_pool_expr_p PARAMS ((rtx)); extern int toc_relative_expr_p PARAMS ((rtx)); extern int expand_block_move PARAMS ((rtx[])); extern int load_multiple_operation PARAMS ((rtx, enum machine_mode)); +extern const char * rs6000_output_load_multiple PARAMS ((rtx[])); extern int store_multiple_operation PARAMS ((rtx, enum machine_mode)); extern int branch_comparison_operator PARAMS ((rtx, enum machine_mode)); extern int branch_positive_comparison_operator diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 2adb119406f7..23d73f334595 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -77,6 +77,9 @@ int rs6000_altivec_abi; /* Set to non-zero once AIX common-mode calls have been defined. */ static int common_mode_defined; +/* Private copy of original value of flag_pic for ABI_AIX. */ +static int rs6000_flag_pic; + /* Save information from a "cmpxx" operation until the branch or scc is emitted. */ rtx rs6000_compare_op0, rs6000_compare_op1; @@ -484,11 +487,8 @@ rs6000_override_options (default_cpu) if (flag_pic != 0 && DEFAULT_ABI == ABI_AIX) { + rs6000_flag_pic = flag_pic; flag_pic = 0; - - if (extra_warnings) - warning ("-f%s ignored (all code is position independent)", - (flag_pic > 1) ? "PIC" : "pic"); } #ifdef XCOFF_DEBUGGING_INFO @@ -5220,6 +5220,64 @@ store_multiple_operation (op, mode) return 1; } +/* Return a string to perform a load_multiple operation. + operands[0] is the vector. + operands[1] is the source address. + operands[2] is the first destination register. */ + +const char * +rs6000_output_load_multiple (operands) + rtx operands[2]; +{ + /* We have to handle the case where the pseudo used to contain the address + is assigned to one of the output registers. */ + int i, j; + int words = XVECLEN (operands[0], 0); + rtx xop[10]; + + if (XVECLEN (operands[0], 0) == 1) + return "{l|lwz} %2,0(%1)"; + + for (i = 0; i < words; i++) + if (refers_to_regno_p (REGNO (operands[2]) + i, + REGNO (operands[2]) + i + 1, operands[1], 0)) + { + if (i == words-1) + { + xop[0] = GEN_INT (4 * (words-1)); + xop[1] = operands[1]; + xop[2] = operands[2]; + output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop); + return ""; + } + else if (i == 0) + { + xop[0] = GEN_INT (4 * (words-1)); + xop[1] = operands[1]; + xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1); + output_asm_insn ("{cal %1,4(%1)|addi %1,%1,4}\n\t{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,-4(%1)", xop); + return ""; + } + else + { + for (j = 0; j < words; j++) + if (j != i) + { + xop[0] = GEN_INT (j * 4); + xop[1] = operands[1]; + xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j); + output_asm_insn ("{l|lwz} %2,%0(%1)", xop); + } + xop[0] = GEN_INT (i * 4); + xop[1] = operands[1]; + output_asm_insn ("{l|lwz} %1,%0(%1)", xop); + return ""; + } + } + + return "{lsi|lswi} %2,%1,%N0"; +} + /* Return 1 for a parallel vrsave operation. */ int @@ -10897,8 +10955,12 @@ rs6000_encode_section_info (decl) if (TREE_CODE (decl) == FUNCTION_DECL) { rtx sym_ref = XEXP (DECL_RTL (decl), 0); - if ((TREE_ASM_WRITTEN (decl) || ! TREE_PUBLIC (decl)) - && ! DECL_WEAK (decl)) + if (!TREE_PUBLIC (decl) + || (!DECL_EXTERNAL (decl) + && !DECL_ONE_ONLY (decl) + && !DECL_WEAK (decl) + && !flag_pic + && !rs6000_flag_pic)) SYMBOL_REF_FLAG (sym_ref) = 1; if (DEFAULT_ABI == ABI_AIX) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 6e86d734f663..ec16c1918637 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -8734,65 +8734,120 @@ adjust_address (op1, SImode, i * 4)); }") -(define_insn "" +(define_insn "*ldmsi8" [(match_parallel 0 "load_multiple_operation" - [(set (match_operand:SI 1 "gpc_reg_operand" "=r") - (mem:SI (match_operand:SI 2 "gpc_reg_operand" "b")))])] - "TARGET_STRING" + [(set (match_operand:SI 2 "gpc_reg_operand" "") + (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) + (set (match_operand:SI 3 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 4)))) + (set (match_operand:SI 4 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 8)))) + (set (match_operand:SI 5 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 12)))) + (set (match_operand:SI 6 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 16)))) + (set (match_operand:SI 7 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 20)))) + (set (match_operand:SI 8 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 24)))) + (set (match_operand:SI 9 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 28))))])] + "TARGET_STRING && XVECLEN (operands[0], 0) == 8" "* -{ - /* We have to handle the case where the pseudo used to contain the address - is assigned to one of the output registers. */ - int i, j; - int words = XVECLEN (operands[0], 0); - rtx xop[10]; +{ return rs6000_output_load_multiple (operands); }" + [(set_attr "type" "load") + (set_attr "length" "32")]) - if (XVECLEN (operands[0], 0) == 1) - return \"{l|lwz} %1,0(%2)\"; +(define_insn "*ldmsi7" + [(match_parallel 0 "load_multiple_operation" + [(set (match_operand:SI 2 "gpc_reg_operand" "") + (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) + (set (match_operand:SI 3 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 4)))) + (set (match_operand:SI 4 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 8)))) + (set (match_operand:SI 5 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 12)))) + (set (match_operand:SI 6 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 16)))) + (set (match_operand:SI 7 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 20)))) + (set (match_operand:SI 8 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 24))))])] + "TARGET_STRING && XVECLEN (operands[0], 0) == 7" + "* +{ return rs6000_output_load_multiple (operands); }" + [(set_attr "type" "load") + (set_attr "length" "32")]) - for (i = 0; i < words; i++) - if (refers_to_regno_p (REGNO (operands[1]) + i, - REGNO (operands[1]) + i + 1, operands[2], 0)) - { - if (i == words-1) - { - xop[0] = operands[1]; - xop[1] = operands[2]; - xop[2] = GEN_INT (4 * (words-1)); - output_asm_insn (\"{lsi|lswi} %0,%1,%2\;{l|lwz} %1,%2(%1)\", xop); - return \"\"; - } - else if (i == 0) - { - xop[0] = operands[1]; - xop[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1); - xop[2] = GEN_INT (4 * (words-1)); - output_asm_insn (\"{cal %0,4(%0)|addi %0,%0,4}\;{lsi|lswi} %1,%0,%2\;{l|lwz} %0,-4(%0)\", xop); - return \"\"; - } - else - { - for (j = 0; j < words; j++) - if (j != i) - { - xop[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + j); - xop[1] = operands[2]; - xop[2] = GEN_INT (j * 4); - output_asm_insn (\"{l|lwz} %0,%2(%1)\", xop); - } - xop[0] = operands[2]; - xop[1] = GEN_INT (i * 4); - output_asm_insn (\"{l|lwz} %0,%1(%0)\", xop); - return \"\"; - } - } +(define_insn "*ldmsi6" + [(match_parallel 0 "load_multiple_operation" + [(set (match_operand:SI 2 "gpc_reg_operand" "") + (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) + (set (match_operand:SI 3 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 4)))) + (set (match_operand:SI 4 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 8)))) + (set (match_operand:SI 5 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 12)))) + (set (match_operand:SI 6 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 16)))) + (set (match_operand:SI 7 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 20))))])] + "TARGET_STRING && XVECLEN (operands[0], 0) == 6" + "* +{ return rs6000_output_load_multiple (operands); }" + [(set_attr "type" "load") + (set_attr "length" "32")]) - return \"{lsi|lswi} %1,%2,%N0\"; -}" +(define_insn "*ldmsi5" + [(match_parallel 0 "load_multiple_operation" + [(set (match_operand:SI 2 "gpc_reg_operand" "") + (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) + (set (match_operand:SI 3 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 4)))) + (set (match_operand:SI 4 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 8)))) + (set (match_operand:SI 5 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 12)))) + (set (match_operand:SI 6 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 16))))])] + "TARGET_STRING && XVECLEN (operands[0], 0) == 5" + "* +{ return rs6000_output_load_multiple (operands); }" + [(set_attr "type" "load") + (set_attr "length" "32")]) + +(define_insn "*ldmsi4" + [(match_parallel 0 "load_multiple_operation" + [(set (match_operand:SI 2 "gpc_reg_operand" "") + (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) + (set (match_operand:SI 3 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 4)))) + (set (match_operand:SI 4 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 8)))) + (set (match_operand:SI 5 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 12))))])] + "TARGET_STRING && XVECLEN (operands[0], 0) == 4" + "* +{ return rs6000_output_load_multiple (operands); }" + [(set_attr "type" "load") + (set_attr "length" "32")]) + +(define_insn "*ldmsi3" + [(match_parallel 0 "load_multiple_operation" + [(set (match_operand:SI 2 "gpc_reg_operand" "") + (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) + (set (match_operand:SI 3 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 4)))) + (set (match_operand:SI 4 "gpc_reg_operand" "") + (mem:SI (plus:SI (match_dup 1) (const_int 8))))])] + "TARGET_STRING && XVECLEN (operands[0], 0) == 3" + "* +{ return rs6000_output_load_multiple (operands); }" [(set_attr "type" "load") (set_attr "length" "32")]) - (define_expand "store_multiple" [(match_par_dup 3 [(set (match_operand:SI 0 "" "") (match_operand:SI 1 "" "")) @@ -8837,7 +8892,7 @@ gen_rtx_REG (SImode, regno + i)); }") -(define_insn "" +(define_insn "*store_multiple_power" [(match_parallel 0 "store_multiple_operation" [(set (match_operand:SI 1 "indirect_operand" "=Q") (match_operand:SI 2 "gpc_reg_operand" "r")) @@ -8846,7 +8901,7 @@ "{stsi|stswi} %2,%P1,%O0" [(set_attr "type" "store")]) -(define_insn "" +(define_insn "*store_multiple_string" [(match_parallel 0 "store_multiple_operation" [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) (match_operand:SI 2 "gpc_reg_operand" "r"))