diff --git a/contrib/gcc/Makefile.in b/contrib/gcc/Makefile.in index 5afd30ef0467..366919bb962a 100644 --- a/contrib/gcc/Makefile.in +++ b/contrib/gcc/Makefile.in @@ -1383,7 +1383,8 @@ varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(RTL_H) flags.h \ $(HASHTAB_H) $(TARGET_H) langhooks.h function.o : function.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h \ function.h $(EXPR_H) libfuncs.h $(REGS_H) hard-reg-set.h \ - insn-config.h $(RECOG_H) output.h toplev.h except.h hash.h $(GGC_H) $(TM_P_H) + insn-config.h $(RECOG_H) output.h toplev.h except.h hash.h $(GGC_H) \ + $(TM_P_H) langhooks.h stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) flags.h function.h \ insn-config.h hard-reg-set.h $(EXPR_H) libfuncs.h except.h \ $(LOOP_H) $(RECOG_H) toplev.h output.h varray.h $(GGC_H) $(TM_P_H) diff --git a/contrib/gcc/config/i386/i386.md b/contrib/gcc/config/i386/i386.md index 4275675ce159..36a0497818eb 100644 --- a/contrib/gcc/config/i386/i386.md +++ b/contrib/gcc/config/i386/i386.md @@ -5311,7 +5311,7 @@ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") (match_operand:DI 2 "general_operand" "roiF,riF"))) (clobber (reg:CC 17))] - "!TARGET_64BIT" + "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" "#") (define_split @@ -6940,7 +6940,7 @@ (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") (match_operand:DI 2 "general_operand" "roiF,riF"))) (clobber (reg:CC 17))] - "!TARGET_64BIT" + "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" "#") (define_split diff --git a/contrib/gcc/function.c b/contrib/gcc/function.c index 9ddf676b5aba..b326d10e69da 100644 --- a/contrib/gcc/function.c +++ b/contrib/gcc/function.c @@ -59,6 +59,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "ggc.h" #include "tm_p.h" #include "integrate.h" +#include "langhooks.h" #ifndef TRAMPOLINE_ALIGNMENT #define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY @@ -826,7 +827,8 @@ assign_stack_temp_for_type (mode, size, keep, type) /* If a type is specified, set the relevant flags. */ if (type != 0) { - RTX_UNCHANGING_P (slot) = TYPE_READONLY (type); + RTX_UNCHANGING_P (slot) = (lang_hooks.honor_readonly + && TYPE_READONLY (type)); MEM_VOLATILE_P (slot) = TYPE_VOLATILE (type); MEM_SET_IN_STRUCT_P (slot, AGGREGATE_TYPE_P (type)); } diff --git a/contrib/gcc/reload.c b/contrib/gcc/reload.c index 80678d0d7b9a..71ed1d6771c3 100644 --- a/contrib/gcc/reload.c +++ b/contrib/gcc/reload.c @@ -242,7 +242,7 @@ static int push_secondary_reload PARAMS ((int, rtx, int, int, enum reg_class, #endif static enum reg_class find_valid_class PARAMS ((enum machine_mode, int, unsigned int)); -static int reload_inner_reg_of_subreg PARAMS ((rtx, enum machine_mode)); +static int reload_inner_reg_of_subreg PARAMS ((rtx, enum machine_mode, int)); static void push_replacement PARAMS ((rtx *, int, enum machine_mode)); static void combine_reloads PARAMS ((void)); static int find_reusable_reload PARAMS ((rtx *, rtx, enum reg_class, @@ -794,9 +794,10 @@ find_reusable_reload (p_in, out, class, type, opnum, dont_share) SUBREG_REG expression. */ static int -reload_inner_reg_of_subreg (x, mode) +reload_inner_reg_of_subreg (x, mode, output) rtx x; enum machine_mode mode; + int output; { rtx inner; @@ -824,6 +825,7 @@ reload_inner_reg_of_subreg (x, mode) word and the number of regs for INNER is not the same as the number of words in INNER, then INNER will need reloading. */ return (GET_MODE_SIZE (mode) <= UNITS_PER_WORD + && output && GET_MODE_SIZE (GET_MODE (inner)) > UNITS_PER_WORD && ((GET_MODE_SIZE (GET_MODE (inner)) / UNITS_PER_WORD) != HARD_REGNO_NREGS (REGNO (inner), GET_MODE (inner)))); @@ -1047,7 +1049,7 @@ push_reload (in, out, inloc, outloc, class, /* Similar issue for (SUBREG constant ...) if it was not handled by the code above. This can happen if SUBREG_BYTE != 0. */ - if (in != 0 && reload_inner_reg_of_subreg (in, inmode)) + if (in != 0 && reload_inner_reg_of_subreg (in, inmode, 0)) { enum reg_class in_class = class; @@ -1144,7 +1146,7 @@ push_reload (in, out, inloc, outloc, class, However, we must reload the inner reg *as well as* the subreg in that case. In this case, the inner reg is an in-out reload. */ - if (out != 0 && reload_inner_reg_of_subreg (out, outmode)) + if (out != 0 && reload_inner_reg_of_subreg (out, outmode, 1)) { /* This relies on the fact that emit_reload_insns outputs the instructions for output reloads of type RELOAD_OTHER in reverse @@ -1722,7 +1724,8 @@ combine_reloads () && ! (GET_CODE (rld[i].in) == REG && reg_overlap_mentioned_for_reload_p (rld[i].in, rld[output_reload].out)))) - && ! reload_inner_reg_of_subreg (rld[i].in, rld[i].inmode) + && ! reload_inner_reg_of_subreg (rld[i].in, rld[i].inmode, + rld[i].when_needed != RELOAD_FOR_INPUT) && (reg_class_size[(int) rld[i].class] || SMALL_REGISTER_CLASSES) /* We will allow making things slightly worse by combining an @@ -4424,20 +4427,12 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest, insn, reg_equiv_constant[regno])) != 0) return tem; - if (GET_MODE_BITSIZE (GET_MODE (x)) == BITS_PER_WORD - && regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0 - && reg_equiv_constant[regno] != 0 - && (tem = operand_subword (reg_equiv_constant[regno], - SUBREG_BYTE (x) / UNITS_PER_WORD, 0, - GET_MODE (SUBREG_REG (x)))) != 0) + if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0 + && reg_equiv_constant[regno] != 0) { - /* TEM is now a word sized constant for the bits from X that - we wanted. However, TEM may be the wrong representation. - - Use gen_lowpart_common to convert a CONST_INT into a - CONST_DOUBLE and vice versa as needed according to by the mode - of the SUBREG. */ - tem = gen_lowpart_common (GET_MODE (x), tem); + tem = + simplify_gen_subreg (GET_MODE (x), reg_equiv_constant[regno], + GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x)); if (!tem) abort (); return tem;