rs6000.c (rs6000_outout_load_multiple): New function.
* config/rs6000/rs6000.c (rs6000_outout_load_multiple): New function. * config/rs6000/rs6000.md (movti_string): Remove output modifier when scratch register never needed. (ldmsi[3-8]): New patterns. From-SVN: r59174
This commit is contained in:
parent
476c5eb60e
commit
9caa3eb2db
@ -1,3 +1,10 @@
|
||||
2002-11-16 David Edelsohn <edelsohn@gnu.org>
|
||||
|
||||
* config/rs6000/rs6000.c (rs6000_outout_load_multiple): New function.
|
||||
* config/rs6000/rs6000.md (movti_string): Remove output modifier
|
||||
when scratch register never needed.
|
||||
(ldmsi[3-8]): New patterns.
|
||||
|
||||
2002-11-16 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
* hard-reg-set.h: Follow spelling conventions.
|
||||
|
@ -84,6 +84,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
|
||||
@ -186,7 +187,7 @@ extern void rs6000_emit_load_toc_table PARAMS ((int));
|
||||
extern void rs6000_aix_emit_builtin_unwind_init PARAMS ((void));
|
||||
extern void rs6000_emit_epilogue PARAMS ((int));
|
||||
extern void debug_stack_info PARAMS ((rs6000_stack_t *));
|
||||
extern const char *output_isel PARAMS ((rtx *));
|
||||
extern const char * output_isel PARAMS ((rtx *));
|
||||
extern int vrsave_operation PARAMS ((rtx, enum machine_mode));
|
||||
extern int rs6000_register_move_cost PARAMS ((enum machine_mode,
|
||||
enum reg_class, enum reg_class));
|
||||
|
@ -6390,6 +6390,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
|
||||
|
@ -9250,7 +9250,7 @@
|
||||
(define_insn "*movti_string"
|
||||
[(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r")
|
||||
(match_operand:TI 1 "reg_or_mem_operand" "r,r,r,Q,m"))
|
||||
(clobber (match_scratch:SI 2 "=X,X,X,X,X"))]
|
||||
(clobber (match_scratch:SI 2 "X,X,X,X,X"))]
|
||||
"TARGET_STRING && ! TARGET_POWER && ! TARGET_POWERPC64
|
||||
&& (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
|
||||
"*
|
||||
@ -9371,65 +9371,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 "" ""))
|
||||
@ -9474,7 +9529,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"))
|
||||
@ -9483,7 +9538,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"))
|
||||
|
Loading…
Reference in New Issue
Block a user