From: Zack Weinberg Date: Tue, 16 Dec 2003 23:55:19 +0000 (+0000) Subject: Backport the following patches from mainline. X-Git-Tag: releases/gcc-3.3.3~188 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=10af679c061eef188382fe47d89d0c0d7ff29501;p=thirdparty%2Fgcc.git Backport the following patches from mainline. 2003-12-05 Mark Mitchell * config/ia64/ia64.h (MUST_PASS_IN_STACK): Define. 2003-12-01 James E Wilson * config/ia64/ia64.h (FUNCTION_ARG_REGNO_P): Use AR_REG_FIRST not GR_ARG_FIRST. 2003-10-21 Zack Weinberg * config/ia64/ia64.md (cmpxchg_acq_si): Mark operand 3 as DImode. * config/ia64/ia64.c (ia64_expand_fetch_and_op, ia64_expand_op_and_fetch): Make sure the REG for ar.ccv is DImode. Use convert_move to load ar.ccv. (ia64_expand_compare_and_swap): Likewise. If expand_expr doesn't put 'old' and 'new' in the proper modes, run them through convert_to_mode. 2003-10-14 Steve Ellcey * config/ia64/ia64.c (ia64_expand_call): Force function address to DImode. * config/ia64/ia64.md (call_gp): Put DImode on operand 0. 2003-06-11 Richard Henderson * config/ia64/ia64.md (call_gp): Fix memory mode. 2003-05-14 Eric Christopher * combine.c: Fix header comments. (distribute_notes): Remove usage of elim_i1, elim_i2. Propagate to all calls and prototype. From-SVN: r74719 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5b0216b6229d..78f5984796fa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,42 @@ +2003-12-16 Zack Weinberg + + Backport the following patches from mainline. + + 2003-12-05 Mark Mitchell + + * config/ia64/ia64.h (MUST_PASS_IN_STACK): Define. + + 2003-12-01 James E Wilson + + * config/ia64/ia64.h (FUNCTION_ARG_REGNO_P): Use AR_REG_FIRST not + GR_ARG_FIRST. + + 2003-10-21 Zack Weinberg + + * config/ia64/ia64.md (cmpxchg_acq_si): Mark operand 3 as DImode. + * config/ia64/ia64.c (ia64_expand_fetch_and_op, + ia64_expand_op_and_fetch): Make sure the REG for ar.ccv is + DImode. Use convert_move to load ar.ccv. + (ia64_expand_compare_and_swap): Likewise. + If expand_expr doesn't put 'old' and 'new' in the proper + modes, run them through convert_to_mode. + + 2003-10-14 Steve Ellcey + + * config/ia64/ia64.c (ia64_expand_call): Force function address + to DImode. + * config/ia64/ia64.md (call_gp): Put DImode on operand 0. + + 2003-06-11 Richard Henderson + + * config/ia64/ia64.md (call_gp): Fix memory mode. + + 2003-05-14 Eric Christopher + + * combine.c: Fix header comments. + (distribute_notes): Remove usage of elim_i1, elim_i2. Propagate + to all calls and prototype. + 2003-12-16 David O'Brien * config/alpha/freebsd.h (FBSD_TARGET_CPU_CPP_BUILTINS): Add __LP64__. @@ -9,7 +48,7 @@ * altivec.h (vec_cmple, vec_all_numeric): Fix typo. * testsuite/gcc.dg/altivec-10.c: Test for above. - + 2003-12-15 Kazu Hirata PR target/13122 @@ -127,8 +166,8 @@ Graham Reed PR target/13150 - * collect2.c (GCC_OK_SYMBOL): Add support for AIX C_WEAKEXT. - (GCC_UNDEF_SYMBOL): Same. + * collect2.c (GCC_OK_SYMBOL): Add support for AIX C_WEAKEXT. + (GCC_UNDEF_SYMBOL): Same. 2003-12-08 Andrew Pinski @@ -189,7 +228,7 @@ (SHLIB_LC): Define. * unwind-libunwind.c (_Unwind_GetCFA): Implement. (_Unwind_GetBSP) [UNW_TARGET_IA64]: New function. - + 2003-12-03 Jakub Jelinek * expr.c (store_constructor): Only set RTX_UNCHANGING_P for @@ -235,7 +274,7 @@ 2002-11-19 Kaz Kojima * config.gcc (sh*-*-linux*): Add t-slibgcc-elf-ver and t-linux. - to tmake_file. + to tmake_file. * config/sh/libgcc-glibc.ver: New file. Backport from mainline diff --git a/gcc/combine.c b/gcc/combine.c index cec5a29cf511..7b0e6a6f8063 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -53,10 +53,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA flow.c aren't completely updated: - reg_live_length is not updated - - reg_n_refs is not adjusted in the rare case when a register is - no longer required in a computation - - there are extremely rare cases (see distribute_regnotes) when a - REG_DEAD note is lost - a LOG_LINKS entry that refers to an insn with multiple SETs may be removed because there is no way to know which register it was linking @@ -417,7 +413,7 @@ static void reg_dead_at_p_1 PARAMS ((rtx, rtx, void *)); static int reg_dead_at_p PARAMS ((rtx, rtx)); static void move_deaths PARAMS ((rtx, rtx, int, rtx, rtx *)); static int reg_bitfield_target_p PARAMS ((rtx, rtx)); -static void distribute_notes PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx)); +static void distribute_notes PARAMS ((rtx, rtx, rtx, rtx)); static void distribute_links PARAMS ((rtx)); static void mark_used_regs_combine PARAMS ((rtx)); static int insn_cuid PARAMS ((rtx)); @@ -2562,7 +2558,7 @@ try_combine (i3, i2, i1, new_direct_jump_p) REG_N_DEATHS (REGNO (XEXP (note, 0)))++; distribute_notes (new_other_notes, undobuf.other_insn, - undobuf.other_insn, NULL_RTX, NULL_RTX, NULL_RTX); + undobuf.other_insn, NULL_RTX); } #ifdef HAVE_cc0 /* If I2 is the setter CC0 and I3 is the user CC0 then check whether @@ -2586,15 +2582,6 @@ try_combine (i3, i2, i1, new_direct_jump_p) rtx i3links, i2links, i1links = 0; rtx midnotes = 0; unsigned int regno; - /* Compute which registers we expect to eliminate. newi2pat may be setting - either i3dest or i2dest, so we must check it. Also, i1dest may be the - same as i3dest, in which case newi2pat may be setting i1dest. */ - rtx elim_i2 = ((newi2pat && reg_set_p (i2dest, newi2pat)) - || i2dest_in_i2src || i2dest_in_i1src - ? 0 : i2dest); - rtx elim_i1 = (i1 == 0 || i1dest_in_i1src - || (newi2pat && reg_set_p (i1dest, newi2pat)) - ? 0 : i1dest); /* Get the old REG_NOTES and LOG_LINKS from all our insns and clear them. */ @@ -2725,17 +2712,13 @@ try_combine (i3, i2, i1, new_direct_jump_p) /* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3. */ if (i3notes) - distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL_RTX, - elim_i2, elim_i1); + distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULL_RTX); if (i2notes) - distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL_RTX, - elim_i2, elim_i1); + distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULL_RTX); if (i1notes) - distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL_RTX, - elim_i2, elim_i1); + distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULL_RTX); if (midnotes) - distribute_notes (midnotes, NULL_RTX, i3, newi2pat ? i2 : NULL_RTX, - elim_i2, elim_i1); + distribute_notes (midnotes, NULL_RTX, i3, newi2pat ? i2 : NULL_RTX); /* Distribute any notes added to I2 or I3 by recog_for_combine. We know these are REG_UNUSED and want them to go to the desired insn, @@ -2748,7 +2731,7 @@ try_combine (i3, i2, i1, new_direct_jump_p) if (GET_CODE (XEXP (temp, 0)) == REG) REG_N_DEATHS (REGNO (XEXP (temp, 0)))++; - distribute_notes (new_i2_notes, i2, i2, NULL_RTX, NULL_RTX, NULL_RTX); + distribute_notes (new_i2_notes, i2, i2, NULL_RTX); } if (new_i3_notes) @@ -2757,7 +2740,7 @@ try_combine (i3, i2, i1, new_direct_jump_p) if (GET_CODE (XEXP (temp, 0)) == REG) REG_N_DEATHS (REGNO (XEXP (temp, 0)))++; - distribute_notes (new_i3_notes, i3, i3, NULL_RTX, NULL_RTX, NULL_RTX); + distribute_notes (new_i3_notes, i3, i3, NULL_RTX); } /* If I3DEST was used in I3SRC, it really died in I3. We may need to @@ -2775,12 +2758,11 @@ try_combine (i3, i2, i1, new_direct_jump_p) if (newi2pat && reg_set_p (i3dest_killed, newi2pat)) distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed, NULL_RTX), - NULL_RTX, i2, NULL_RTX, elim_i2, elim_i1); + NULL_RTX, i2, NULL_RTX); else distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i3dest_killed, NULL_RTX), - NULL_RTX, i3, newi2pat ? i2 : NULL_RTX, - elim_i2, elim_i1); + NULL_RTX, i3, newi2pat ? i2 : NULL_RTX); } if (i2dest_in_i2src) @@ -2790,11 +2772,10 @@ try_combine (i3, i2, i1, new_direct_jump_p) if (newi2pat && reg_set_p (i2dest, newi2pat)) distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX), - NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX); + NULL_RTX, i2, NULL_RTX); else distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i2dest, NULL_RTX), - NULL_RTX, i3, newi2pat ? i2 : NULL_RTX, - NULL_RTX, NULL_RTX); + NULL_RTX, i3, newi2pat ? i2 : NULL_RTX); } if (i1dest_in_i1src) @@ -2804,11 +2785,10 @@ try_combine (i3, i2, i1, new_direct_jump_p) if (newi2pat && reg_set_p (i1dest, newi2pat)) distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX), - NULL_RTX, i2, NULL_RTX, NULL_RTX, NULL_RTX); + NULL_RTX, i2, NULL_RTX); else distribute_notes (gen_rtx_EXPR_LIST (REG_DEAD, i1dest, NULL_RTX), - NULL_RTX, i3, newi2pat ? i2 : NULL_RTX, - NULL_RTX, NULL_RTX); + NULL_RTX, i3, newi2pat ? i2 : NULL_RTX); } distribute_links (i3links); @@ -12532,19 +12512,14 @@ reg_bitfield_target_p (x, body) as appropriate. I3 and I2 are the insns resulting from the combination insns including FROM (I2 may be zero). - ELIM_I2 and ELIM_I1 are either zero or registers that we know will - not need REG_DEAD notes because they are being substituted for. This - saves searching in the most common cases. - Each note in the list is either ignored or placed on some insns, depending on the type of note. */ static void -distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) +distribute_notes (notes, from_insn, i3, i2) rtx notes; rtx from_insn; rtx i3, i2; - rtx elim_i2, elim_i1; { rtx note, next_note; rtx tem; @@ -12807,10 +12782,6 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) && reg_referenced_p (XEXP (note, 0), PATTERN (i2))) place = i2; - if (rtx_equal_p (XEXP (note, 0), elim_i2) - || rtx_equal_p (XEXP (note, 0), elim_i1)) - break; - if (place == 0) { basic_block bb = this_basic_block; @@ -12868,7 +12839,7 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) PATTERN (tem) = pc_rtx; distribute_notes (REG_NOTES (tem), tem, tem, - NULL_RTX, NULL_RTX, NULL_RTX); + NULL_RTX); distribute_links (LOG_LINKS (tem)); PUT_CODE (tem, NOTE); @@ -12883,7 +12854,7 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) distribute_notes (REG_NOTES (cc0_setter), cc0_setter, cc0_setter, - NULL_RTX, NULL_RTX, NULL_RTX); + NULL_RTX); distribute_links (LOG_LINKS (cc0_setter)); PUT_CODE (cc0_setter, NOTE); @@ -13037,7 +13008,7 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) = gen_rtx_EXPR_LIST (REG_DEAD, piece, NULL_RTX); distribute_notes (new_note, place, place, - NULL_RTX, NULL_RTX, NULL_RTX); + NULL_RTX); } else if (! refers_to_regno_p (i, i + 1, PATTERN (place), 0) diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 9242afbab8d5..21447c99ded1 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -1431,6 +1431,7 @@ ia64_expand_call (retval, addr, nextarg, sibcall_p) rtx insn, b0; addr = XEXP (addr, 0); + addr = convert_memory_address (DImode, addr); b0 = gen_rtx_REG (DImode, R_BR (0)); /* ??? Should do this for functions known to bind local too. */ @@ -7880,13 +7881,14 @@ ia64_expand_fetch_and_op (binoptab, mode, arglist, target) } tmp = gen_reg_rtx (mode); - ccv = gen_rtx_REG (mode, AR_CCV_REGNUM); + /* ar.ccv must always be loaded with a zero-extended DImode value. */ + ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM); emit_move_insn (tmp, mem); label = gen_label_rtx (); emit_label (label); emit_move_insn (ret, tmp); - emit_move_insn (ccv, tmp); + convert_move (ccv, tmp, /*unsignedp=*/1); /* Perform the specific operation. Special case NAND by noticing one_cmpl_optab instead. */ @@ -7949,14 +7951,15 @@ ia64_expand_op_and_fetch (binoptab, mode, arglist, target) emit_insn (gen_mf ()); tmp = gen_reg_rtx (mode); old = gen_reg_rtx (mode); - ccv = gen_rtx_REG (mode, AR_CCV_REGNUM); + /* ar.ccv must always be loaded with a zero-extended DImode value. */ + ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM); emit_move_insn (tmp, mem); label = gen_label_rtx (); emit_label (label); emit_move_insn (old, tmp); - emit_move_insn (ccv, tmp); + convert_move (ccv, tmp, /*unsignedp=*/1); /* Perform the specific operation. Special case NAND by noticing one_cmpl_optab instead. */ @@ -8009,6 +8012,11 @@ ia64_expand_compare_and_swap (rmode, mode, boolp, arglist, target) mem = gen_rtx_MEM (mode, force_reg (ptr_mode, mem)); MEM_VOLATILE_P (mem) = 1; + if (GET_MODE (old) != mode) + old = convert_to_mode (mode, old, /*unsignedp=*/1); + if (GET_MODE (new) != mode) + new = convert_to_mode (mode, new, /*unsignedp=*/1); + if (! register_operand (old, mode)) old = copy_to_mode_reg (mode, old); if (! register_operand (new, mode)) @@ -8020,14 +8028,7 @@ ia64_expand_compare_and_swap (rmode, mode, boolp, arglist, target) tmp = gen_reg_rtx (mode); ccv = gen_rtx_REG (DImode, AR_CCV_REGNUM); - if (mode == DImode) - emit_move_insn (ccv, old); - else - { - rtx ccvtmp = gen_reg_rtx (DImode); - emit_insn (gen_zero_extendsidi2 (ccvtmp, old)); - emit_move_insn (ccv, ccvtmp); - } + convert_move (ccv, old, /*unsignedp=*/1); emit_insn (gen_mf ()); if (mode == SImode) insn = gen_cmpxchg_acq_si (tmp, mem, new, ccv); diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h index 1d37dfa41a4f..2a3e409e1b22 100644 --- a/gcc/config/ia64/ia64.h +++ b/gcc/config/ia64/ia64.h @@ -1289,6 +1289,13 @@ enum reg_class #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ ia64_function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED) +/* Nonzero if we do not know how to pass TYPE solely in registers. */ + +#define MUST_PASS_IN_STACK(MODE, TYPE) \ + ((TYPE) != 0 \ + && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \ + || TREE_ADDRESSABLE (TYPE))) + /* A C type for declaring a variable that is used as the first argument of `FUNCTION_ARG' and other related values. For some target machines, the type `int' suffices and can hold the number of bytes of argument so far. */ @@ -1353,7 +1360,7 @@ do { \ On many machines, no registers can be used for this purpose since all function arguments are pushed on the stack. */ #define FUNCTION_ARG_REGNO_P(REGNO) \ -(((REGNO) >= GR_ARG_FIRST && (REGNO) < (GR_ARG_FIRST + MAX_ARGUMENT_SLOTS)) \ +(((REGNO) >= AR_ARG_FIRST && (REGNO) < (AR_ARG_FIRST + MAX_ARGUMENT_SLOTS)) \ || ((REGNO) >= FR_ARG_FIRST && (REGNO) < (FR_ARG_FIRST + MAX_ARGUMENT_SLOTS))) /* Implement `va_arg'. */ diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md index 3b88d9f81c36..f711f13e9d3e 100644 --- a/gcc/config/ia64/ia64.md +++ b/gcc/config/ia64/ia64.md @@ -4802,7 +4802,7 @@ [(set_attr "itanium_class" "br,scall")]) (define_insn "call_gp" - [(call (mem (match_operand 0 "call_operand" "?r,i")) + [(call (mem:DI (match_operand:DI 0 "call_operand" "?r,i")) (const_int 1)) (clobber (match_operand:DI 1 "register_operand" "=b,b")) (clobber (match_scratch:DI 2 "=&r,X")) @@ -5451,7 +5451,7 @@ (set (match_operand:SI 1 "not_postinc_memory_operand" "+S") (unspec:SI [(match_dup 1) (match_operand:SI 2 "gr_register_operand" "r") - (match_operand 3 "ar_ccv_reg_operand" "")] + (match_operand:DI 3 "ar_ccv_reg_operand" "")] UNSPEC_CMPXCHG_ACQ))] "" "cmpxchg4.acq %0 = %1, %2, %3"