diff options
author | Eric Christopher <echristo@gcc.gnu.org> | 2005-08-10 19:52:55 +0000 |
---|---|---|
committer | Eric Christopher <echristo@gcc.gnu.org> | 2005-08-10 19:52:55 +0000 |
commit | bb8df8a62d346532834194e96b8d3970eb8cd6e0 (patch) | |
tree | 7a3055424b4a8f77e035af7455a562a19bcc5135 | |
parent | 4f8dbd340cd7e0181a24666bb82ea9fea5a78565 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 143 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 22 |
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 |