aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Christopher <echristo@gcc.gnu.org>2005-08-10 19:52:55 +0000
committerEric Christopher <echristo@gcc.gnu.org>2005-08-10 19:52:55 +0000
commitbb8df8a62d346532834194e96b8d3970eb8cd6e0 (patch)
tree7a3055424b4a8f77e035af7455a562a19bcc5135
parent4f8dbd340cd7e0181a24666bb82ea9fea5a78565 (diff)
downloadgcc-bb8df8a62d346532834194e96b8d3970eb8cd6e0.zip
gcc-bb8df8a62d346532834194e96b8d3970eb8cd6e0.tar.gz
gcc-bb8df8a62d346532834194e96b8d3970eb8cd6e0.tar.bz2
rs6000.c (mems_ok_for_quad_peep): Rewrite.
2005-08-10 Eric Christopher <echristo@apple.com> * config/rs6000/rs6000.c (mems_ok_for_quad_peep): Rewrite. * config/rs6000/rs6000.md (*lfq_power2, *stfq_power2): Use V2DFmode. From-SVN: r102956
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/rs6000/rs6000.c143
-rw-r--r--gcc/config/rs6000/rs6000.md22
3 files changed, 96 insertions, 77 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6a6159b..e6a0339 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-08-10 Eric Christopher <echristo@apple.com>
+
+ * config/rs6000/rs6000.c (mems_ok_for_quad_peep): Rewrite.
+ * config/rs6000/rs6000.md (*lfq_power2, *stfq_power2): Use
+ V2DFmode.
+
2005-08-10 Andrew Pinski <pinskia@physics.uc.edu>
* config/darwin.c (machopic_indirect_data_reference): Use a new register
@@ -74,7 +80,7 @@
2005-08-09 Dorit Nuzman <dorit@il.ibm.com>
- * tree-vect-transform.c (vect_create_epilog_for_reduction): Set
+ * tree-vect-transform.c (vect_create_epilog_for_reduction): Set
BIT_FIELD_REF_UNSIGNED for newly created BIT_FIELD_REFs.
2005-08-09 Richard Guenther <rguenther@suse.de>
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 4cb97c5..577bbfb 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1975,7 +1975,7 @@ int
num_insns_constant (rtx op, enum machine_mode mode)
{
HOST_WIDE_INT low, high;
-
+
switch (GET_CODE (op))
{
case CONST_INT:
@@ -1992,7 +1992,7 @@ num_insns_constant (rtx op, enum machine_mode mode)
{
long l;
REAL_VALUE_TYPE rv;
-
+
REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
REAL_VALUE_TO_TARGET_SINGLE (rv, l);
return num_insns_constant_wide ((HOST_WIDE_INT) l);
@@ -2007,7 +2007,7 @@ num_insns_constant (rtx op, enum machine_mode mode)
{
long l[2];
REAL_VALUE_TYPE rv;
-
+
REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
high = l[WORDS_BIG_ENDIAN == 0];
@@ -2022,18 +2022,18 @@ num_insns_constant (rtx op, enum machine_mode mode)
if ((high == 0 && low >= 0)
|| (high == -1 && low < 0))
return num_insns_constant_wide (low);
-
+
else if (mask_operand (op, mode))
return 2;
-
+
else if (low == 0)
return num_insns_constant_wide (high) + 1;
-
+
else
return (num_insns_constant_wide (high)
+ num_insns_constant_wide (low) + 1);
}
-
+
default:
gcc_unreachable ();
}
@@ -2128,7 +2128,7 @@ output_vec_const_move (rtx *operands)
return "vxor %0,%0,%0";
gcc_assert (easy_vector_constant (vec, mode));
-
+
operands[1] = GEN_INT (cst);
switch (mode)
{
@@ -2162,14 +2162,14 @@ output_vec_const_move (rtx *operands)
}
else if (EASY_VECTOR_15_ADD_SELF (cst))
return "#";
-
+
default:
gcc_unreachable ();
}
}
gcc_assert (TARGET_SPE);
-
+
/* Vector constant 0 is handled as a splitter of V2SI, and in the
pattern of V1DI, V4HI, and V2SF.
@@ -2355,7 +2355,7 @@ mask64_1or2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED,
{
HOST_WIDE_INT c, lsb;
bool one_ok;
-
+
c = INTVAL (op);
/* Disallow all zeros. */
@@ -2366,7 +2366,7 @@ mask64_1or2_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED,
AND there are zero, one or two transitions in the _whole_ of
C. */
one_ok = !(c & ~(HOST_WIDE_INT)0xffffffff);
-
+
/* We don't change the number of transitions by inverting,
so make sure we start with the LS bit zero. */
if (c & 1)
@@ -2501,7 +2501,7 @@ rs6000_special_round_type_align (tree type, int computed, int specified)
{
tree field = TYPE_FIELDS (type);
- /* Skip all non field decls */
+ /* Skip all non field decls */
while (field != NULL && TREE_CODE (field) != FIELD_DECL)
field = TREE_CHAIN (field);
@@ -3574,10 +3574,10 @@ rs6000_emit_set_const (rtx dest, enum machine_mode mode,
dest = gen_reg_rtx (mode);
emit_insn (gen_rtx_SET (VOIDmode, dest, source));
return dest;
-
+
case SImode:
result = no_new_pseudos ? dest : gen_reg_rtx (SImode);
-
+
emit_insn (gen_rtx_SET (VOIDmode, result,
GEN_INT (INTVAL (source)
& (~ (HOST_WIDE_INT) 0xffff))));
@@ -3594,7 +3594,7 @@ rs6000_emit_set_const (rtx dest, enum machine_mode mode,
c0 = INTVAL (source);
c1 = -(c0 < 0);
break;
-
+
case CONST_DOUBLE:
#if HOST_BITS_PER_WIDE_INT >= 64
c0 = CONST_DOUBLE_LOW (source);
@@ -3758,7 +3758,7 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
|| CONST_DOUBLE_LOW (operands[1]) < 0)
&& (CONST_DOUBLE_HIGH (operands[1]) != -1
|| CONST_DOUBLE_LOW (operands[1]) >= 0)));
-
+
/* Check if GCC is setting up a block move that will end up using FP
registers as temporaries. We must make sure this is acceptable. */
if (GET_CODE (operands[0]) == MEM
@@ -4549,7 +4549,7 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
grovel through the fields for these too. */
cum->intoffset = 0;
rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
- rs6000_darwin64_record_arg_advance_flush (cum,
+ rs6000_darwin64_record_arg_advance_flush (cum,
size * BITS_PER_UNIT);
}
}
@@ -4711,7 +4711,7 @@ rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
structure between cum->intoffset and bitpos to integer registers. */
static void
-rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
+rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
HOST_WIDE_INT bitpos, rtx rvec[], int *k)
{
enum machine_mode mode;
@@ -4755,7 +4755,7 @@ rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
cum->use_stack = 1;
-
+
intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
if (intregs <= 0)
return;
@@ -4779,7 +4779,7 @@ rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
/* Recursive workhorse for the following. */
static void
-rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, tree type,
+rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, tree type,
HOST_WIDE_INT startbitpos, rtx rvec[],
int *k)
{
@@ -4813,7 +4813,7 @@ rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, tree type,
#endif
rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
rvec[(*k)++]
- = gen_rtx_EXPR_LIST (VOIDmode,
+ = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (mode, cum->fregno++),
GEN_INT (bitpos / BITS_PER_UNIT));
if (mode == TFmode)
@@ -4823,8 +4823,8 @@ rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, tree type,
{
rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
rvec[(*k)++]
- = gen_rtx_EXPR_LIST (VOIDmode,
- gen_rtx_REG (mode, cum->vregno++),
+ = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (mode, cum->vregno++),
GEN_INT (bitpos / BITS_PER_UNIT));
}
else if (cum->intoffset == -1)
@@ -4837,7 +4837,7 @@ rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, tree type,
being passed by value, along with the offset of where the
register's value may be found in the block. FP fields go in FP
register, vector fields go in vector registers, and everything
- else goes in int registers, packed as in memory.
+ else goes in int registers, packed as in memory.
This code is also used for function return values. RETVAL indicates
whether this is the case.
@@ -5249,7 +5249,7 @@ rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
/* If we are passing this arg in the fixed parameter save area
(gprs or memory) as well as fprs, then this function should
return the number of bytes passed in the parameter save area
- rather than bytes passed in fprs. */
+ rather than bytes passed in fprs. */
&& !(type
&& (cum->nargs_prototype <= 0
|| (DEFAULT_ABI == ABI_AIX
@@ -7736,13 +7736,13 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
}
gcc_assert (TARGET_ALTIVEC || TARGET_SPE);
-
+
/* Handle simple unary operations. */
d = (struct builtin_description *) bdesc_1arg;
for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
if (d->code == fcode)
return rs6000_expand_unop_builtin (d->icode, arglist, target);
-
+
/* Handle simple binary operations. */
d = (struct builtin_description *) bdesc_2arg;
for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
@@ -7754,7 +7754,7 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
if (d->code == fcode)
return rs6000_expand_ternop_builtin (d->icode, arglist, target);
-
+
gcc_unreachable ();
}
@@ -8698,7 +8698,7 @@ rs6000_common_init_builtins (void)
mode2 = insn_data[d->icode].operand[2].mode;
mode3 = insn_data[d->icode].operand[3].mode;
}
-
+
/* When all four are of the same mode. */
if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
{
@@ -8795,7 +8795,7 @@ rs6000_common_init_builtins (void)
mode2 = VOIDmode;
}
else
- {
+ {
if (d->name == 0 || d->icode == CODE_FOR_nothing)
continue;
@@ -8945,7 +8945,7 @@ rs6000_common_init_builtins (void)
{
if (d->name == 0 || d->icode == CODE_FOR_nothing)
continue;
-
+
mode0 = insn_data[d->icode].operand[0].mode;
mode1 = insn_data[d->icode].operand[1].mode;
}
@@ -9647,8 +9647,8 @@ int
mems_ok_for_quad_peep (rtx mem1, rtx mem2)
{
rtx addr1, addr2;
- unsigned int reg1;
- int offset1;
+ unsigned int reg1, reg2;
+ int offset1, offset2;
/* The mems cannot be volatile. */
if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
@@ -9681,23 +9681,36 @@ mems_ok_for_quad_peep (rtx mem1, rtx mem2)
offset1 = 0;
}
- /* Make sure the second address is a (mem (plus (reg) (const_int)))
- or if it is (mem (reg)) then make sure that offset1 is -8 and the same
- register as addr1. */
- if (offset1 == -8 && GET_CODE (addr2) == REG && reg1 == REGNO (addr2))
- return 1;
- if (GET_CODE (addr2) != PLUS)
- return 0;
-
- if (GET_CODE (XEXP (addr2, 0)) != REG
- || GET_CODE (XEXP (addr2, 1)) != CONST_INT)
+ /* And now for the second addr. */
+ if (GET_CODE (addr2) == PLUS)
+ {
+ /* If not a REG, return zero. */
+ if (GET_CODE (XEXP (addr2, 0)) != REG)
+ return 0;
+ else
+ {
+ reg2 = REGNO (XEXP (addr2, 0));
+ /* The offset must be constant. */
+ if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
+ return 0;
+ offset2 = INTVAL (XEXP (addr2, 1));
+ }
+ }
+ else if (GET_CODE (addr2) != REG)
return 0;
+ else
+ {
+ reg2 = REGNO (addr2);
+ /* This was a simple (mem (reg)) expression. Offset is 0. */
+ offset2 = 0;
+ }
- if (reg1 != REGNO (XEXP (addr2, 0)))
+ /* Both of these must have the same base register. */
+ if (reg1 != reg2)
return 0;
/* The offset for the second addr must be 8 more than the first addr. */
- if (INTVAL (XEXP (addr2, 1)) != offset1 + 8)
+ if (offset2 != offset1 + 8)
return 0;
/* All the tests passed. addr1 and addr2 are valid for lfq or stfq
@@ -10617,7 +10630,7 @@ print_operand (FILE *file, rtx x, int code)
{
gcc_assert (GET_CODE (tmp) == PLUS
&& GET_CODE (XEXP (tmp, 1)) == REG);
-
+
if (REGNO (XEXP (tmp, 0)) == 0)
fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
reg_names[ REGNO (XEXP (tmp, 0)) ]);
@@ -10918,7 +10931,7 @@ rs6000_generate_compare (enum rtx_code code)
gcc_unreachable ();
}
break;
-
+
case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
switch (op_mode)
{
@@ -10929,7 +10942,7 @@ rs6000_generate_compare (enum rtx_code code)
: gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1);
break;
-
+
case DFmode:
cmp = flag_unsafe_math_optimizations
? gen_tstdfgt_gpr (compare_result, rs6000_compare_op0,
@@ -10942,7 +10955,7 @@ rs6000_generate_compare (enum rtx_code code)
gcc_unreachable ();
}
break;
-
+
case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
switch (op_mode)
{
@@ -10953,7 +10966,7 @@ rs6000_generate_compare (enum rtx_code code)
: gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
rs6000_compare_op1);
break;
-
+
case DFmode:
cmp = flag_unsafe_math_optimizations
? gen_tstdflt_gpr (compare_result, rs6000_compare_op0,
@@ -11577,7 +11590,7 @@ rs6000_emit_vector_select (rtx dest, rtx op1, rtx op2, rtx mask)
temp = gen_reg_rtx (dest_mode);
- /* For each vector element, select op1 when mask is 1 otherwise
+ /* For each vector element, select op1 when mask is 1 otherwise
select op2. */
t = gen_rtx_SET (VOIDmode, temp,
gen_rtx_UNSPEC (dest_mode,
@@ -11867,7 +11880,7 @@ rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
(set M (CODE:MODE M OP))
If not NULL, BEFORE is atomically set to M before the operation, and
AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
- If SYNC_P then a memory barrier is emitted before the operation.
+ If SYNC_P then a memory barrier is emitted before the operation.
Either OP or M may be wrapped in a NOT operation. */
void
@@ -11881,10 +11894,10 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
rtvec vec;
HOST_WIDE_INT imask = GET_MODE_MASK (mode);
rtx shift = NULL_RTX;
-
+
if (sync_p)
emit_insn (gen_memory_barrier ());
-
+
if (GET_CODE (m) == NOT)
used_m = XEXP (m, 0);
else
@@ -11901,14 +11914,14 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
int ishift = 0;
if (BYTES_BIG_ENDIAN)
ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
-
+
shift = GEN_INT (ishift);
}
else
{
rtx addrSI, aligned_addr;
int shift_mask = mode == QImode ? 0x18 : 0x10;
-
+
addrSI = force_reg (SImode, gen_lowpart_common (SImode,
XEXP (used_m, 0)));
shift = gen_reg_rtx (SImode);
@@ -11961,7 +11974,7 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
case MINUS:
{
rtx mask;
-
+
newop = expand_binop (SImode, and_optab,
oldop, GEN_INT (imask), NULL_RTX,
1, OPTAB_LIB_WIDEN);
@@ -12016,7 +12029,7 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
if (after == NULL_RTX)
after = gen_reg_rtx (used_mode);
}
-
+
if ((code == PLUS || code == MINUS || GET_CODE (m) == NOT)
&& used_mode != mode)
the_op = op; /* Computed above. */
@@ -12109,7 +12122,7 @@ emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
}
/* Expand an an atomic fetch-and-operate pattern. CODE is the binary operation
- to perform. MEM is the memory on which to operate. VAL is the second
+ to perform. MEM is the memory on which to operate. VAL is the second
operand of the binary operator. BEFORE and AFTER are optional locations to
return the value of MEM either before of after the operation. SCRATCH is
a scratch register. */
@@ -13361,7 +13374,7 @@ rs6000_emit_load_toc_table (int fromprolog)
else
{
gcc_assert (DEFAULT_ABI == ABI_AIX);
-
+
if (TARGET_32BIT)
insn = emit_insn (gen_load_toc_aix_si (dest));
else
@@ -17767,7 +17780,7 @@ rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
return orig;
gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
-
+
/* Use a different reg for the intermediate value, as
it will be marked UNCHANGING. */
reg_temp = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
@@ -17776,7 +17789,7 @@ rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
offset =
rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
Pmode, reg);
-
+
if (GET_CODE (offset) == CONST_INT)
{
if (SMALL_INT (offset))
@@ -18990,8 +19003,8 @@ rs6000_vector_mode_supported_p (enum machine_mode mode)
return false;
}
-/* Target hook for invalid_arg_for_unprototyped_fn. */
-static const char *
+/* Target hook for invalid_arg_for_unprototyped_fn. */
+static const char *
invalid_arg_for_unprototyped_fn (tree typelist, tree funcdecl, tree val)
{
return (!rs6000_darwin64_abi
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 05ff9bd..288b40f 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -4830,7 +4830,7 @@
(match_dup 3)
(match_dup 4)))]
"TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
- && !HONOR_NANS (SFmode) && !HONOR_SIGNED_ZEROS (SFmode)"
+ && !HONOR_NANS (SFmode) && !HONOR_SIGNED_ZEROS (SFmode)"
{
operands[3] = gen_reg_rtx (SFmode);
operands[4] = gen_reg_rtx (SFmode);
@@ -9144,11 +9144,11 @@
;; Peephole to convert two consecutive FP loads or stores into lfq/stfq.
(define_insn "*lfq_power2"
- [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
- (match_operand:TF 1 "memory_operand" ""))]
+ [(set (match_operand:V2DF 0 "gpc_reg_operand" "=f")
+ (match_operand:V2DF 1 "memory_operand" ""))]
"TARGET_POWER2
&& TARGET_HARD_FLOAT && TARGET_FPRS"
- "lfq%U1%X1 %0,%1")
+ "lfq%U1%X1 %0,%1")
(define_peephole2
[(set (match_operand:DF 0 "gpc_reg_operand" "")
@@ -9160,13 +9160,13 @@
&& registers_ok_for_quad_peep (operands[0], operands[2])
&& mems_ok_for_quad_peep (operands[1], operands[3])"
[(set (match_dup 0)
- (match_dup 1))]
- "operands[1] = widen_memory_access (operands[1], TFmode, 0);
- operands[0] = gen_rtx_REG (TFmode, REGNO (operands[0]));")
+ (match_dup 1))]
+ "operands[1] = widen_memory_access (operands[1], V2DFmode, 0);
+ operands[0] = gen_rtx_REG (V2DFmode, REGNO (operands[0]));")
(define_insn "*stfq_power2"
- [(set (match_operand:TF 0 "memory_operand" "")
- (match_operand:TF 1 "gpc_reg_operand" "f"))]
+ [(set (match_operand:V2DF 0 "memory_operand" "")
+ (match_operand:V2DF 1 "gpc_reg_operand" "f"))]
"TARGET_POWER2
&& TARGET_HARD_FLOAT && TARGET_FPRS"
"stfq%U0%X0 %1,%0")
@@ -9183,8 +9183,8 @@
&& mems_ok_for_quad_peep (operands[0], operands[2])"
[(set (match_dup 0)
(match_dup 1))]
- "operands[0] = widen_memory_access (operands[0], TFmode, 0);
- operands[1] = gen_rtx_REG (TFmode, REGNO (operands[1]));")
+ "operands[0] = widen_memory_access (operands[0], V2DFmode, 0);
+ operands[1] = gen_rtx_REG (V2DFmode, REGNO (operands[1]));")
;; after inserting conditional returns we can sometimes have
;; unnecessary register moves. Unfortunately we cannot have a