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
This commit is contained in:
David Edelsohn 2002-11-26 15:59:58 +00:00 committed by David Edelsohn
parent 9e2b4bfd5e
commit fe4cded8aa
4 changed files with 190 additions and 62 deletions

View File

@ -1,3 +1,13 @@
2002-11-26 David Edelsohn <edelsohn@gnu.org>
* 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 <ehrhardt@mathematik.uni-ulm.de>
PR c/8639

View File

@ -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

View File

@ -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)

View File

@ -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];
if (XVECLEN (operands[0], 0) == 1)
return \"{l|lwz} %1,0(%2)\";
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 \"\";
}
}
return \"{lsi|lswi} %1,%2,%N0\";
}"
{ return rs6000_output_load_multiple (operands); }"
[(set_attr "type" "load")
(set_attr "length" "32")])
(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")])
(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")])
(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"))