summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-01-15 13:20:06 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2009-01-15 13:20:06 +0000
commitb6d2952820e82733b0686904a9b9b6134ba78e73 (patch)
tree0fbbc1c2d3ef4b3e01100c92cf3d83ab35b48950 /gcc
parentaafb9581fe147e93331850662df862f77fd523ae (diff)
downloadgcc-b6d2952820e82733b0686904a9b9b6134ba78e73.tar.gz
2009-01-15 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk r143392 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@143395 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog146
-rw-r--r--gcc/ChangeLog-20062
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in6
-rw-r--r--gcc/calls.c47
-rw-r--r--gcc/combine.c3
-rw-r--r--gcc/config/alpha/alpha.c19
-rw-r--r--gcc/config/arm/arm.c885
-rw-r--r--gcc/config/i386/i386.c40
-rw-r--r--gcc/cp/ChangeLog20
-rw-r--r--gcc/cp/name-lookup.c3
-rw-r--r--gcc/cp/parser.c135
-rw-r--r--gcc/cp/tree.c6
-rw-r--r--gcc/dce.c304
-rw-r--r--gcc/doc/gty.texi22
-rw-r--r--gcc/doc/invoke.texi11
-rw-r--r--gcc/fortran/ChangeLog4
-rw-r--r--gcc/fortran/ChangeLog-20071
-rw-r--r--gcc/gcc.c19
-rw-r--r--gcc/graphite.c293
-rw-r--r--gcc/graphite.h1
-rw-r--r--gcc/ira-conflicts.c5
-rw-r--r--gcc/ira-lives.c8
-rw-r--r--gcc/testsuite/ChangeLog137
-rw-r--r--gcc/testsuite/ChangeLog-20081
-rw-r--r--gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c3
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr38795.C13
-rw-r--r--gcc/testsuite/g++.dg/eh/check-vect.h5
-rw-r--r--gcc/testsuite/g++.dg/eh/simd-2.C4
-rw-r--r--gcc/testsuite/g++.dg/ext/altivec-2.C3
-rw-r--r--gcc/testsuite/g++.dg/ext/altivec-3.C5
-rw-r--r--gcc/testsuite/g++.dg/ext/altivec-cell-2.C5
-rw-r--r--gcc/testsuite/g++.dg/ext/altivec-cell-3.C5
-rw-r--r--gcc/testsuite/g++.dg/ext/altivec-cell-4.C5
-rw-r--r--gcc/testsuite/g++.dg/ext/altivec_check.h27
-rw-r--r--gcc/testsuite/g++.dg/ext/spe1.C3
-rw-r--r--gcc/testsuite/g++.dg/other/opaque-1.C4
-rw-r--r--gcc/testsuite/g++.dg/other/opaque-2.C3
-rw-r--r--gcc/testsuite/g++.dg/other/opaque-3.C3
-rw-r--r--gcc/testsuite/g++.dg/parse/crash50.C10
-rw-r--r--gcc/testsuite/g++.dg/parse/pr37862.C25
-rw-r--r--gcc/testsuite/g++.dg/torture/pr38811.C73
-rw-r--r--gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-pta-1.c19
-rw-r--r--gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c3
-rw-r--r--gcc/testsuite/gcc.dg/graphite/pr38786.c20
-rw-r--r--gcc/testsuite/gcc.dg/pr38245-3.c112
-rw-r--r--gcc/testsuite/gcc.dg/pr38245-3.h35
-rw-r--r--gcc/testsuite/gcc.dg/pr38245-4.c107
-rw-r--r--gcc/testsuite/gcc.dg/pr38364.c79
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr38774.c16
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-105.c6
-rw-r--r--gcc/testsuite/gcc.target/arm/eabi1.c8
-rw-r--r--gcc/testsuite/gcc.target/arm/long-calls-1.c56
-rw-r--r--gcc/testsuite/gcc.target/arm/long-calls-2.c46
-rw-r--r--gcc/testsuite/gcc.target/arm/long-calls-3.c127
-rw-r--r--gcc/testsuite/gcc.target/arm/long-calls-4.c113
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-10.c2
-rw-r--r--gcc/testsuite/gcc.target/mips/mips.exp9
-rw-r--r--gcc/testsuite/gcc.target/powerpc/20030218-1.c7
-rw-r--r--gcc/testsuite/gcc.target/powerpc/20030505.c3
-rw-r--r--gcc/testsuite/gcc.target/powerpc/20081204-1.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-1.c6
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-10.c9
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-12.c7
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-24.c5
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-3.c7
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-cell-2.c5
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-cell-3.c5
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-cell-4.c5
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-cell-8.c7
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-consts.c7
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-macros.c27
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-varargs-1.c10
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec-vec-merge.c5
-rw-r--r--gcc/testsuite/gcc.target/powerpc/altivec_check.h43
-rw-r--r--gcc/testsuite/gcc.target/powerpc/ppc-spe.c3
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr35907.c6
-rw-r--r--gcc/testsuite/gcc.target/powerpc/spe-vector-memcpy.c6
-rw-r--r--gcc/testsuite/gcc.target/powerpc/spe1.c3
-rw-r--r--gcc/testsuite/lib/target-supports.exp51
-rw-r--r--gcc/tree-ssa-structalias.c35
81 files changed, 2500 insertions, 838 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e3ccd794827..aeab680011b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,137 @@
+2009-01-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/38245
+ * calls.c (expand_call): Add stack arguments to
+ CALL_INSN_FUNCTION_USAGE even for pure calls (when
+ ACCUMULATE_OUTGOING_ARGS) and even for args partially passed
+ in regs and partially in memory or BLKmode arguments.
+ (emit_library_call_value_1): Add stack arguments to
+ CALL_INSN_FUNCTION_USAGE even for pure calls (when
+ ACCUMULATE_OUTGOING_ARGS).
+ * dce.c: Include tm_p.h.
+ (find_call_stack_args): New function.
+ (deletable_insn_p): Call it for CALL_P insns. Add ARG_STORES
+ argument.
+ (mark_insn): Call find_call_stack_args for CALL_Ps.
+ (prescan_insns_for_dce): Walk insns backwards in bb rather than
+ forwards. Allocate and free arg_stores bitmap if needed, pass it
+ down to deletable_insn_p, don't mark stores set in arg_stores
+ bitmap, clear the bitmap at the beginning of each bb.
+ * Makefile.in (dce.o): Depend on $(TM_P_H).
+
+2009-01-14 Michael Meissner <gnu@the-meissners.org>
+
+ PR target/22599
+ * i386.c (print_operand): Add tests for 'D', 'C', 'F', 'f' to make
+ sure the insn is a conditional test (bug 22599). Reformat a few long
+ lines.
+
+2009-01-14 Sebastian Pop <sebastian.pop@amd.com>
+
+ PR middle-end/38431
+ * graphite.c (get_vdef_before_scop, scop_adjust_vphi): New.
+ (scop_adjust_phis_for_liveouts): Call scop_adjust_vphi.
+ (gloog): Do not call cleanup_tree_cfg.
+ (graphite_transform_loops): Call cleanup_tree_cfg after all
+ scops have been code generated.
+
+2009-01-14 Vladimir Makarov <vmakarov@redhat.com>
+
+ * testsuite/g++.dg/torture/pr38811.C: New file.
+
+2009-01-14 Basile Starynkevitch <basile@starynkevitch.net>
+ * doc/gty.texi (Invoking the garbage collector): Added new node
+ and section documenting ggc_collect.
+
+2009-01-14 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/38826
+ PR middle-end/38477
+ * tree-ssa-structalias.c (emit_alias_warning): Emit the pointer
+ initialization notes only if we actually emitted a warning.
+ (intra_create_variable_infos): Add constraints for a result decl
+ that is passed by hidden reference.
+ (build_pred_graph): Mark all related variables non-direct on
+ address-taking.
+
+2009-01-14 Nick Clifton <nickc@redhat.com>
+
+ * ira-conflicts.c: Include addresses.h for the definition of
+ base_reg_class.
+ (ira_build_conflicts): Use base_reg_class instead of
+ BASE_REG_CLASS.
+ * Makefile.in: Add a dependency of ira-conflicts.o on
+ addresses.h.
+
+2009-01-13 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR target/38811
+ * Makefile.in (ira-lives.o): Add except.h.
+
+ * ira-lives.c: Include except.h.
+ (process_bb_node_lives): Process can_throw_internal.
+
+2009-01-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/38774
+ * combine.c (simplify_set): When undoing cc_use change, don't do
+ PUT_CODE on the newly created comparison, but instead put back the
+ old comparison.
+
+2009-01-13 Joseph Myers <joseph@codesourcery.com>
+
+ * doc/invoke.texi (ARM Options): Update lists of -mcpu and -march
+ values. Remove duplicate arm8 entry.
+
+2009-01-13 Sebastian Pop <sebastian.pop@amd.com>
+
+ PR tree-optimization/38786
+ * graphite.c (expand_scalar_variables_ssa_name): New, outlined from
+ the SSA_NAME case of expand_scalar_variables_expr.
+ Set the type of an expression to the type of its assign statement.
+ (expand_scalar_variables_expr): Also gather the scalar computation
+ used to index the memory access. Do not pass loop_p.
+ Fix comment. Stop recursion on tcc_constant or tcc_declaration.
+ (expand_scalar_variables_stmt): Pass to expand_scalar_variables_expr
+ the gimple_stmt_iterator where it inserts new code. Do not pass loop_p.
+ (copy_bb_and_scalar_dependences): Do not pass loop_p.
+ (translate_clast): Update call to copy_bb_and_scalar_dependences.
+
+2009-01-13 Sebastian Pop <sebastian.pop@amd.com>
+
+ * graphite.h (debug_value): Removed.
+ * graphite.c (debug_value): Removed.
+
+2009-01-13 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (output_move_double): Don't synthesize thumb-2 ldrd/strd with
+ two 32-bit instructions.
+
+2009-01-13 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (struct processors): Pass for speed down into cost helper
+ functions.
+ (const_ok_for_op): Handle COMPARE and inequality nodes.
+ (arm_rtx_costs_1): Rewrite.
+ (arm_size_rtx_costs): Update prototype.
+ (arm_rtx_costs): Pass speed down to helper functions.
+ (arm_slowmul_rtx_costs): Rework cost calculations.
+ (arm_fastmul_rtx_costs, arm_xscale_rtx_costs): Likewise.
+ (arm_9e_rtx_costs): Likewise.
+
+2009-01-13 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.c (alpha_legitimate_address_p): Explicit
+ relocations of local symbols wider than UNITS_PER_WORD are not valid.
+ (alpha_legitimize_address): Do not split local symbols wider than
+ UNITS_PER_WORD into HIGH/LO_SUM parts.
+
+2009-01-13 Danny Smith <dannysmith@users.sourceforge.net>
+
+ PR bootstrap/38580
+ * gcc.c (process_command): Replace call to execvp with calls
+ to pex_one and exit.
+
2009-01-03 Anatoly Sokolov <aesok@post.ru>
PR target/29141
@@ -26,9 +160,9 @@
2009-01-12 Tomas Bily <tbily@suse.cz>
PR middlend/38385
- * tree-loop-distribution.c (prop_phis): New function.
- (generate_builtin): Call prop_phis.
- * testsuite/gcc.dg/tree-ssa/pr38385.c: New file.
+ * tree-loop-distribution.c (prop_phis): New function.
+ (generate_builtin): Call prop_phis.
+ * testsuite/gcc.dg/tree-ssa/pr38385.c: New file.
2009-01-12 Jakub Jelinek <jakub@redhat.com>
@@ -79,8 +213,7 @@
2008-01-09 Vladimir Makarov <vmakarov@redhat.com>
PR rtl-optimization/38495
- * ira-emit.c (print_move_list, ira_debug_move_list): New
- functions.
+ * ira-emit.c (print_move_list, ira_debug_move_list): New functions.
(add_range_and_copies_from_move_list): Print all added ranges.
Add ranges to memory optimized destination.
@@ -105,8 +238,7 @@
epilogue_size_needed to the epilogue expanders.
PR c/35742
- * c-pretty-print.c (pp_c_expression): Handle GOTO_EXPR like
- BIND_EXPR.
+ * c-pretty-print.c (pp_c_expression): Handle GOTO_EXPR like BIND_EXPR.
2009-01-09 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
diff --git a/gcc/ChangeLog-2006 b/gcc/ChangeLog-2006
index 00d47c29139..d57f42548e3 100644
--- a/gcc/ChangeLog-2006
+++ b/gcc/ChangeLog-2006
@@ -22671,7 +22671,7 @@
* basic-block.h: Remove the prototype for
partition_hot_cold_basic_blocks.
-2006-01-16 Rafael Ãvila de EspÃ�­ndola <rafael.espindola@gmail.com>
+2006-01-16 Rafael Ãvila de Espíndola <rafael.espindola@gmail.com>
* cppspec.c (lang_specific_spec_functions): Remove.
* gcc.c (lookup_spec_function): Use static_spec_functions directly.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 6933e22e43b..a188b88a9ef 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20090113
+20090114
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 3e83138868d..d819716e730 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2738,7 +2738,7 @@ cse.o : cse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
$(DF_H) $(DBGCNT_H)
dce.o : dce.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) $(DF_H) cselib.h \
- $(DBGCNT_H) dce.h $(TIMEVAR_H) tree-pass.h $(DBGCNT_H)
+ $(DBGCNT_H) dce.h $(TIMEVAR_H) tree-pass.h $(DBGCNT_H) $(TM_P_H)
dse.o : dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(TM_P_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
$(RECOG_H) $(EXPR_H) $(DF_H) cselib.h $(DBGCNT_H) $(TIMEVAR_H) tree-pass.h \
@@ -2992,7 +2992,7 @@ ira-costs.o: ira-costs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
ira-conflicts.o: ira-conflicts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(PARAMS_H) \
- $(DF_H) sparseset.h $(IRA_INT_H)
+ $(DF_H) sparseset.h addresses.h $(IRA_INT_H)
ira-color.o: ira-color.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
$(EXPR_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(PARAMS_H) \
@@ -3002,7 +3002,7 @@ ira-emit.o: ira-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(EXPR_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(PARAMS_H) \
$(IRA_INT_H)
ira-lives.o: ira-lives.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TARGET_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \
+ $(TARGET_H) $(RTL_H) $(REGS_H) except.h hard-reg-set.h $(FLAGS_H) \
insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) $(TOPLEV_H) $(TM_P_H) $(PARAMS_H) \
$(DF_H) sparseset.h $(IRA_INT_H)
ira.o: ira.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
diff --git a/gcc/calls.c b/gcc/calls.c
index f6bc970b71b..a75e3b36569 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1,6 +1,6 @@
/* Convert function calls to rtl insns, for GNU C compiler.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GCC.
@@ -2705,26 +2705,28 @@ expand_call (tree exp, rtx target, int ignore)
but we do preallocate space here if they want that. */
for (i = 0; i < num_actuals; i++)
- if (args[i].reg == 0 || args[i].pass_on_stack)
- {
- rtx before_arg = get_last_insn ();
-
- if (store_one_arg (&args[i], argblock, flags,
- adjusted_args_size.var != 0,
- reg_parm_stack_space)
- || (pass == 0
- && check_sibcall_argument_overlap (before_arg,
- &args[i], 1)))
- sibcall_failure = 1;
-
- if (flags & ECF_CONST
- && args[i].stack
- && args[i].value == args[i].stack)
- call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
- gen_rtx_USE (VOIDmode,
- args[i].value),
- call_fusage);
- }
+ {
+ if (args[i].reg == 0 || args[i].pass_on_stack)
+ {
+ rtx before_arg = get_last_insn ();
+
+ if (store_one_arg (&args[i], argblock, flags,
+ adjusted_args_size.var != 0,
+ reg_parm_stack_space)
+ || (pass == 0
+ && check_sibcall_argument_overlap (before_arg,
+ &args[i], 1)))
+ sibcall_failure = 1;
+ }
+
+ if (((flags & ECF_CONST)
+ || ((flags & ECF_PURE) && ACCUMULATE_OUTGOING_ARGS))
+ && args[i].stack)
+ call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_USE (VOIDmode,
+ args[i].stack),
+ call_fusage);
+ }
/* If we have a parm that is passed in registers but not in memory
and whose alignment does not permit a direct copy into registers,
@@ -3672,7 +3674,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
NO_DEFER_POP;
- if (flags & ECF_CONST)
+ if ((flags & ECF_CONST)
+ || ((flags & ECF_PURE) && ACCUMULATE_OUTGOING_ARGS))
{
rtx use;
diff --git a/gcc/combine.c b/gcc/combine.c
index 82bf9f5e115..3aca075aae1 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -5706,6 +5706,7 @@ simplify_set (rtx x)
{
int other_changed_previously = other_changed;
unsigned HOST_WIDE_INT mask;
+ rtx old_cc_use = *cc_use;
SUBST (*cc_use, gen_rtx_fmt_ee (new_code, GET_MODE (*cc_use),
dest, const0_rtx));
@@ -5728,7 +5729,7 @@ simplify_set (rtx x)
if ((recog_for_combine (&pat, other_insn, &note) < 0
&& ! check_asm_operands (pat)))
{
- PUT_CODE (*cc_use, old_code);
+ *cc_use = old_cc_use;
other_changed = 0;
op0 = simplify_gen_binary (XOR, GET_MODE (op0),
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 9c79f8883fc..7bafb0ae84b 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -864,9 +864,11 @@ alpha_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
}
}
- /* If we're managing explicit relocations, LO_SUM is valid, as
- are small data symbols. */
- else if (TARGET_EXPLICIT_RELOCS)
+ /* If we're managing explicit relocations, LO_SUM is valid, as are small
+ data symbols. Avoid explicit relocations of modes larger than word
+ mode since i.e. $LC0+8($1) can fold around +/- 32k offset. */
+ else if (TARGET_EXPLICIT_RELOCS
+ && GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
{
if (small_symbolic_operand (x, Pmode))
return true;
@@ -916,8 +918,7 @@ get_tls_get_addr (void)
to be legitimate. If we find one, return the new, valid address. */
rtx
-alpha_legitimize_address (rtx x, rtx scratch,
- enum machine_mode mode ATTRIBUTE_UNUSED)
+alpha_legitimize_address (rtx x, rtx scratch, enum machine_mode mode)
{
HOST_WIDE_INT addend;
@@ -965,8 +966,12 @@ alpha_legitimize_address (rtx x, rtx scratch,
goto split_addend;
}
- /* If this is a local symbol, split the address into HIGH/LO_SUM parts. */
- if (TARGET_EXPLICIT_RELOCS && symbolic_operand (x, Pmode))
+ /* If this is a local symbol, split the address into HIGH/LO_SUM parts.
+ Avoid modes larger than word mode since i.e. $LC0+8($1) can fold
+ around +/- 32k offset. */
+ if (TARGET_EXPLICIT_RELOCS
+ && GET_MODE_SIZE (mode) <= UNITS_PER_WORD
+ && symbolic_operand (x, Pmode))
{
rtx r0, r16, eqv, tga, tp, insn, dest, seq;
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index dce0a523bd4..209682bb0fe 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -126,12 +126,12 @@ static bool arm_function_ok_for_sibcall (tree, tree);
static void arm_internal_label (FILE *, const char *, unsigned long);
static void arm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
tree);
-static int arm_rtx_costs_1 (rtx, enum rtx_code, enum rtx_code);
-static bool arm_size_rtx_costs (rtx, int, int, int *);
-static bool arm_slowmul_rtx_costs (rtx, int, int, int *);
-static bool arm_fastmul_rtx_costs (rtx, int, int, int *);
-static bool arm_xscale_rtx_costs (rtx, int, int, int *);
-static bool arm_9e_rtx_costs (rtx, int, int, int *);
+static bool arm_rtx_costs_1 (rtx, enum rtx_code, int*, bool);
+static bool arm_size_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *);
+static bool arm_slowmul_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *, bool);
+static bool arm_fastmul_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *, bool);
+static bool arm_xscale_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *, bool);
+static bool arm_9e_rtx_costs (rtx, enum rtx_code, enum rtx_code, int *, bool);
static bool arm_rtx_costs (rtx, int, int, int *, bool);
static int arm_address_cost (rtx, bool);
static bool arm_memory_load_p (rtx);
@@ -619,7 +619,7 @@ struct processors
enum processor_type core;
const char *arch;
const unsigned long flags;
- bool (* rtx_costs) (rtx, int, int, int *);
+ bool (* rtx_costs) (rtx, enum rtx_code, enum rtx_code, int *, bool);
};
/* Not all of these give usefully different compilation alternatives,
@@ -1883,6 +1883,24 @@ const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code)
switch (code)
{
case PLUS:
+ case COMPARE:
+ case EQ:
+ case NE:
+ case GT:
+ case LE:
+ case LT:
+ case GE:
+ case GEU:
+ case LTU:
+ case GTU:
+ case LEU:
+ case UNORDERED:
+ case ORDERED:
+ case UNEQ:
+ case UNGE:
+ case UNLT:
+ case UNGT:
+ case UNLE:
return const_ok_for_arm (ARM_SIGN_EXTEND (-i));
case MINUS: /* Should only occur with (MINUS I reg) => rsb */
@@ -4882,130 +4900,227 @@ thumb1_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer)
}
}
-
-/* Worker routine for arm_rtx_costs. */
-/* ??? This needs updating for thumb2. */
-static inline int
-arm_rtx_costs_1 (rtx x, enum rtx_code code, enum rtx_code outer)
+static inline bool
+arm_rtx_costs_1 (rtx x, enum rtx_code outer, int* total, bool speed)
{
enum machine_mode mode = GET_MODE (x);
enum rtx_code subcode;
+ rtx operand;
+ enum rtx_code code = GET_CODE (x);
int extra_cost;
+ *total = 0;
switch (code)
{
case MEM:
/* Memory costs quite a lot for the first word, but subsequent words
load at the equivalent of a single insn each. */
- return (10 + 4 * ((GET_MODE_SIZE (mode) - 1) / UNITS_PER_WORD)
- + (GET_CODE (x) == SYMBOL_REF
- && CONSTANT_POOL_ADDRESS_P (x) ? 4 : 0));
+ *total = COSTS_N_INSNS (2 + ARM_NUM_REGS (mode));
+ return true;
case DIV:
case MOD:
case UDIV:
case UMOD:
- return optimize_size ? COSTS_N_INSNS (2) : 100;
+ if (TARGET_HARD_FLOAT && mode == SFmode)
+ *total = COSTS_N_INSNS (2);
+ else if (TARGET_HARD_FLOAT && mode == DFmode)
+ *total = COSTS_N_INSNS (4);
+ else
+ *total = COSTS_N_INSNS (20);
+ return false;
case ROTATE:
- if (mode == SImode && GET_CODE (XEXP (x, 1)) == REG)
- return 4;
+ if (GET_CODE (XEXP (x, 1)) == REG)
+ *total = COSTS_N_INSNS (1); /* Need to subtract from 32 */
+ else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
+ *total = rtx_cost (XEXP (x, 1), code, speed);
+
/* Fall through */
case ROTATERT:
if (mode != SImode)
- return 8;
+ {
+ *total += COSTS_N_INSNS (4);
+ return true;
+ }
+
/* Fall through */
case ASHIFT: case LSHIFTRT: case ASHIFTRT:
+ *total += rtx_cost (XEXP (x, 0), code, speed);
if (mode == DImode)
- return (8 + (GET_CODE (XEXP (x, 1)) == CONST_INT ? 0 : 8)
- + ((GET_CODE (XEXP (x, 0)) == REG
- || (GET_CODE (XEXP (x, 0)) == SUBREG
- && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG))
- ? 0 : 8));
+ {
+ *total += COSTS_N_INSNS (3);
+ return true;
+ }
- extra_cost = 1;
+ *total += COSTS_N_INSNS (1);
/* Increase the cost of complex shifts because they aren't any faster,
and reduce dual issue opportunities. */
if (arm_tune_cortex_a9
&& outer != SET && GET_CODE (XEXP (x, 1)) != CONST_INT)
- extra_cost++;
-
- return (extra_cost + ((GET_CODE (XEXP (x, 0)) == REG
- || (GET_CODE (XEXP (x, 0)) == SUBREG
- && GET_CODE (SUBREG_REG (XEXP (x, 0))) == REG))
- ? 0 : 4)
- + ((GET_CODE (XEXP (x, 1)) == REG
- || (GET_CODE (XEXP (x, 1)) == SUBREG
- && GET_CODE (SUBREG_REG (XEXP (x, 1))) == REG)
- || (GET_CODE (XEXP (x, 1)) == CONST_INT))
- ? 0 : 4));
+ ++*total;
+
+ return true;
case MINUS:
- if (GET_CODE (XEXP (x, 1)) == MULT && mode == SImode && arm_arch_thumb2)
+ if (TARGET_THUMB2)
{
- extra_cost = rtx_cost (XEXP (x, 1), code, true);
- if (!REG_OR_SUBREG_REG (XEXP (x, 0)))
- extra_cost += 4 * ARM_NUM_REGS (mode);
- return extra_cost;
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
+ *total = COSTS_N_INSNS (1);
+ else
+ *total = COSTS_N_INSNS (20);
+ }
+ else
+ *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
+ /* Thumb2 does not have RSB, so all arguments must be
+ registers (subtracting a constant is canonicalized as
+ addition of the negated constant). */
+ return false;
}
if (mode == DImode)
- return (4 + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 8)
- + ((REG_OR_SUBREG_REG (XEXP (x, 0))
- || (GET_CODE (XEXP (x, 0)) == CONST_INT
- && const_ok_for_arm (INTVAL (XEXP (x, 0)))))
- ? 0 : 8));
+ {
+ *total = COSTS_N_INSNS (ARM_NUM_REGS (mode));
+ if (GET_CODE (XEXP (x, 0)) == CONST_INT
+ && const_ok_for_arm (INTVAL (XEXP (x, 0))))
+ {
+ *total += rtx_cost (XEXP (x, 1), code, speed);
+ return true;
+ }
+
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ && const_ok_for_arm (INTVAL (XEXP (x, 1))))
+ {
+ *total += rtx_cost (XEXP (x, 0), code, speed);
+ return true;
+ }
+
+ return false;
+ }
if (GET_MODE_CLASS (mode) == MODE_FLOAT)
- return (2 + ((REG_OR_SUBREG_REG (XEXP (x, 1))
- || (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
- && arm_const_double_rtx (XEXP (x, 1))))
- ? 0 : 8)
- + ((REG_OR_SUBREG_REG (XEXP (x, 0))
- || (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE
- && arm_const_double_rtx (XEXP (x, 0))))
- ? 0 : 8));
-
- if (((GET_CODE (XEXP (x, 0)) == CONST_INT
- && const_ok_for_arm (INTVAL (XEXP (x, 0)))
- && REG_OR_SUBREG_REG (XEXP (x, 1))))
- || (((subcode = GET_CODE (XEXP (x, 1))) == ASHIFT
- || subcode == ASHIFTRT || subcode == LSHIFTRT
- || subcode == ROTATE || subcode == ROTATERT
- || (subcode == MULT
- && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
- && ((INTVAL (XEXP (XEXP (x, 1), 1)) &
- (INTVAL (XEXP (XEXP (x, 1), 1)) - 1)) == 0)))
- && REG_OR_SUBREG_REG (XEXP (XEXP (x, 1), 0))
- && (REG_OR_SUBREG_REG (XEXP (XEXP (x, 1), 1))
- || GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT)
- && REG_OR_SUBREG_REG (XEXP (x, 0))))
- return 1;
+ {
+ if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
+ {
+ *total = COSTS_N_INSNS (1);
+ if (GET_CODE (XEXP (x, 0)) == CONST_DOUBLE
+ && arm_const_double_rtx (XEXP (x, 0)))
+ {
+ *total += rtx_cost (XEXP (x, 1), code, speed);
+ return true;
+ }
+
+ if (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
+ && arm_const_double_rtx (XEXP (x, 1)))
+ {
+ *total += rtx_cost (XEXP (x, 0), code, speed);
+ return true;
+ }
+
+ return false;
+ }
+ *total = COSTS_N_INSNS (20);
+ return false;
+ }
+
+ *total = COSTS_N_INSNS (1);
+ if (GET_CODE (XEXP (x, 0)) == CONST_INT
+ && const_ok_for_arm (INTVAL (XEXP (x, 0))))
+ {
+ *total += rtx_cost (XEXP (x, 1), code, speed);
+ return true;
+ }
+
+ subcode = GET_CODE (XEXP (x, 1));
+ if (subcode == ASHIFT || subcode == ASHIFTRT
+ || subcode == LSHIFTRT
+ || subcode == ROTATE || subcode == ROTATERT)
+ {
+ *total += rtx_cost (XEXP (x, 0), code, speed);
+ *total += rtx_cost (XEXP (XEXP (x, 1), 0), subcode, speed);
+ return true;
+ }
+
+ if (subcode == MULT
+ && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
+ && ((INTVAL (XEXP (XEXP (x, 1), 1)) &
+ (INTVAL (XEXP (XEXP (x, 1), 1)) - 1)) == 0))
+ {
+ *total += rtx_cost (XEXP (x, 0), code, speed);
+ *total += rtx_cost (XEXP (XEXP (x, 1), 0), subcode, speed);
+ return true;
+ }
+
+ if (GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == RTX_COMPARE
+ || GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == RTX_COMM_COMPARE)
+ {
+ *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 0), code, speed);
+ if (GET_CODE (XEXP (XEXP (x, 1), 0)) == REG
+ && REGNO (XEXP (XEXP (x, 1), 0)) != CC_REGNUM)
+ *total += COSTS_N_INSNS (1);
+
+ return true;
+ }
+
/* Fall through */
case PLUS:
- if (arm_arch6 && mode == SImode
+ if (code == PLUS && arm_arch6 && mode == SImode
&& (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
|| GET_CODE (XEXP (x, 0)) == SIGN_EXTEND))
- return 1 + (GET_CODE (XEXP (XEXP (x, 0), 0)) == MEM ? 10 : 0)
- + (GET_CODE (XEXP (x, 1)) == MEM ? 10 : 0);
+ {
+ *total = COSTS_N_INSNS (1);
+ *total += rtx_cost (XEXP (XEXP (x, 0), 0), GET_CODE (XEXP (x, 0)),
+ speed);
+ *total += rtx_cost (XEXP (x, 1), code, speed);
+ return true;
+ }
- if (GET_CODE (XEXP (x, 0)) == MULT)
+ /* MLA: All arguments must be registers. We filter out
+ multiplication by a power of two, so that we fall down into
+ the code below. */
+ if (GET_CODE (XEXP (x, 0)) == MULT
+ && ! (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+ && ((INTVAL (XEXP (XEXP (x, 0), 1)) &
+ (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0)))
{
- extra_cost = rtx_cost (XEXP (x, 0), code, true);
- if (!REG_OR_SUBREG_REG (XEXP (x, 1)))
- extra_cost += 4 * ARM_NUM_REGS (mode);
- return extra_cost;
+ /* The cost comes from the cost of the multiply. */
+ return false;
}
if (GET_MODE_CLASS (mode) == MODE_FLOAT)
- return (2 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8)
- + ((REG_OR_SUBREG_REG (XEXP (x, 1))
- || (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
- && arm_const_double_rtx (XEXP (x, 1))))
- ? 0 : 8));
+ {
+ if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
+ {
+ *total = COSTS_N_INSNS (1);
+ if (GET_CODE (XEXP (x, 1)) == CONST_DOUBLE
+ && arm_const_double_rtx (XEXP (x, 1)))
+ {
+ *total += rtx_cost (XEXP (x, 0), code, speed);
+ return true;
+ }
+
+ return false;
+ }
+
+ *total = COSTS_N_INSNS (20);
+ return false;
+ }
+
+ if (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == RTX_COMPARE
+ || GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == RTX_COMM_COMPARE)
+ {
+ *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 1), code, speed);
+ if (GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
+ && REGNO (XEXP (XEXP (x, 0), 0)) != CC_REGNUM)
+ *total += COSTS_N_INSNS (1);
+ return true;
+ }
/* Fall through */
+
case AND: case XOR: case IOR:
extra_cost = 0;
@@ -5019,38 +5134,56 @@ arm_rtx_costs_1 (rtx x, enum rtx_code code, enum rtx_code outer)
&& GET_CODE (XEXP (x, 1)) != CONST_INT)
|| (REG_OR_SUBREG_REG (XEXP (x, 0))
&& ARM_FRAME_RTX (REG_OR_SUBREG_RTX (XEXP (x, 0)))))
- extra_cost = 4;
+ *total = 4;
if (mode == DImode)
- return (4 + extra_cost + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 8)
- + ((REG_OR_SUBREG_REG (XEXP (x, 1))
- || (GET_CODE (XEXP (x, 1)) == CONST_INT
- && const_ok_for_op (INTVAL (XEXP (x, 1)), code)))
- ? 0 : 8));
-
- if (REG_OR_SUBREG_REG (XEXP (x, 0)))
- return (1 + (GET_CODE (XEXP (x, 1)) == CONST_INT ? 0 : extra_cost)
- + ((REG_OR_SUBREG_REG (XEXP (x, 1))
- || (GET_CODE (XEXP (x, 1)) == CONST_INT
- && const_ok_for_op (INTVAL (XEXP (x, 1)), code)))
- ? 0 : 4));
-
- else if (REG_OR_SUBREG_REG (XEXP (x, 1)))
- return (1 + extra_cost
- + ((((subcode = GET_CODE (XEXP (x, 0))) == ASHIFT
- || subcode == LSHIFTRT || subcode == ASHIFTRT
- || subcode == ROTATE || subcode == ROTATERT
- || (subcode == MULT
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
- && ((INTVAL (XEXP (XEXP (x, 0), 1)) &
- (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0)))
- && (REG_OR_SUBREG_REG (XEXP (XEXP (x, 0), 0)))
- && ((REG_OR_SUBREG_REG (XEXP (XEXP (x, 0), 1))
- && !arm_tune_cortex_a9)
- || GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
- ? 0 : 4));
+ {
+ *total += COSTS_N_INSNS (2);
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ && const_ok_for_op (INTVAL (XEXP (x, 1)), code))
+ {
+ *total += rtx_cost (XEXP (x, 0), code, speed);
+ return true;
+ }
- return 8;
+ return false;
+ }
+
+ *total += COSTS_N_INSNS (1);
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ && const_ok_for_op (INTVAL (XEXP (x, 1)), code))
+ {
+ *total += rtx_cost (XEXP (x, 0), code, speed);
+ return true;
+ }
+ subcode = GET_CODE (XEXP (x, 0));
+ if (subcode == ASHIFT || subcode == ASHIFTRT
+ || subcode == LSHIFTRT
+ || subcode == ROTATE || subcode == ROTATERT)
+ {
+ *total += rtx_cost (XEXP (x, 1), code, speed);
+ *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode, speed);
+ return true;
+ }
+
+ if (subcode == MULT
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+ && ((INTVAL (XEXP (XEXP (x, 0), 1)) &
+ (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0))
+ {
+ *total += rtx_cost (XEXP (x, 1), code, speed);
+ *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode, speed);
+ return true;
+ }
+
+ if (subcode == UMIN || subcode == UMAX
+ || subcode == SMIN || subcode == SMAX)
+ {
+ *total = COSTS_N_INSNS (3);
+ return true;
+ }
+
+ return false;
case MULT:
/* This should have been handled by the CPU specific routines. */
@@ -5064,108 +5197,290 @@ arm_rtx_costs_1 (rtx x, enum rtx_code code, enum rtx_code outer)
== GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)))
&& (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == ZERO_EXTEND
|| GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0)) == SIGN_EXTEND))
- return 8;
- return 99;
+ {
+ *total = rtx_cost (XEXP (XEXP (x, 0), 0), LSHIFTRT, speed);
+ return true;
+ }
+ *total = COSTS_N_INSNS (2); /* Plus the cost of the MULT */
+ return false;
case NEG:
if (GET_MODE_CLASS (mode) == MODE_FLOAT)
- return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 6);
+ {
+ if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
+ {
+ *total = COSTS_N_INSNS (1);
+ return false;
+ }
+ *total = COSTS_N_INSNS (2);
+ return false;
+ }
+
/* Fall through */
case NOT:
- if (mode == DImode)
- return 4 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4);
+ *total = COSTS_N_INSNS (ARM_NUM_REGS(mode));
+ if (mode == SImode && code == NOT)
+ {
+ subcode = GET_CODE (XEXP (x, 0));
+ if (subcode == ASHIFT || subcode == ASHIFTRT
+ || subcode == LSHIFTRT
+ || subcode == ROTATE || subcode == ROTATERT
+ || (subcode == MULT
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+ && ((INTVAL (XEXP (XEXP (x, 0), 1)) &
+ (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0)))
+ {
+ *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode, speed);
+ /* Register shifts cost an extra cycle. */
+ if (GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
+ *total += COSTS_N_INSNS (1) + rtx_cost (XEXP (XEXP (x, 0), 1),
+ subcode, speed);
+ return true;
+ }
+ }
- return 1 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4);
+ return false;
case IF_THEN_ELSE:
if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC)
- return 14;
- return 2;
+ {
+ *total = COSTS_N_INSNS (4);
+ return true;
+ }
+ operand = XEXP (x, 0);
+
+ if (!((GET_RTX_CLASS (GET_CODE (operand)) == RTX_COMPARE
+ || GET_RTX_CLASS (GET_CODE (operand)) == RTX_COMM_COMPARE)
+ && GET_CODE (XEXP (operand, 0)) == REG
+ && REGNO (XEXP (operand, 0)) == CC_REGNUM))
+ *total += COSTS_N_INSNS (1);
+ *total += (rtx_cost (XEXP (x, 1), code, speed)
+ + rtx_cost (XEXP (x, 2), code, speed));
+ return true;
+
+ case NE:
+ if (mode == SImode && XEXP (x, 1) == const0_rtx)
+ {
+ *total = COSTS_N_INSNS (2) + rtx_cost (XEXP (x, 0), code, speed);
+ return true;
+ }
+ goto scc_insn;
+
+ case GE:
+ if ((GET_CODE (XEXP (x, 0)) != REG || REGNO (XEXP (x, 0)) != CC_REGNUM)
+ && mode == SImode && XEXP (x, 1) == const0_rtx)
+ {
+ *total = COSTS_N_INSNS (2) + rtx_cost (XEXP (x, 0), code, speed);
+ return true;
+ }
+ goto scc_insn;
+
+ case LT:
+ if ((GET_CODE (XEXP (x, 0)) != REG || REGNO (XEXP (x, 0)) != CC_REGNUM)
+ && mode == SImode && XEXP (x, 1) == const0_rtx)
+ {
+ *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 0), code, speed);
+ return true;
+ }
+ goto scc_insn;
+
+ case EQ:
+ case GT:
+ case LE:
+ case GEU:
+ case LTU:
+ case GTU:
+ case LEU:
+ case UNORDERED:
+ case ORDERED:
+ case UNEQ:
+ case UNGE:
+ case UNLT:
+ case UNGT:
+ case UNLE:
+ scc_insn:
+ /* SCC insns. In the case where the comparison has already been
+ performed, then they cost 2 instructions. Otherwise they need
+ an additional comparison before them. */
+ *total = COSTS_N_INSNS (2);
+ if (GET_CODE (XEXP (x, 0)) == REG && REGNO (XEXP (x, 0)) == CC_REGNUM)
+ {
+ return true;
+ }
+
+ /* Fall through */
case COMPARE:
- return 1;
+ if (GET_CODE (XEXP (x, 0)) == REG && REGNO (XEXP (x, 0)) == CC_REGNUM)
+ {
+ *total = 0;
+ return true;
+ }
+
+ *total += COSTS_N_INSNS (1);
+ if (GET_CODE (XEXP (x, 1)) == CONST_INT
+ && const_ok_for_op (INTVAL (XEXP (x, 1)), code))
+ {
+ *total += rtx_cost (XEXP (x, 0), code, speed);
+ return true;
+ }
+
+ subcode = GET_CODE (XEXP (x, 0));
+ if (subcode == ASHIFT || subcode == ASHIFTRT
+ || subcode == LSHIFTRT
+ || subcode == ROTATE || subcode == ROTATERT)
+ {
+ *total += rtx_cost (XEXP (x, 1), code, speed);
+ *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode, speed);
+ return true;
+ }
+
+ if (subcode == MULT
+ && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
+ && ((INTVAL (XEXP (XEXP (x, 0), 1)) &
+ (INTVAL (XEXP (XEXP (x, 0), 1)) - 1)) == 0))
+ {
+ *total += rtx_cost (XEXP (x, 1), code, speed);
+ *total += rtx_cost (XEXP (XEXP (x, 0), 0), subcode, speed);
+ return true;
+ }
+
+ return false;
+
+ case UMIN:
+ case UMAX:
+ case SMIN:
+ case SMAX:
+ *total = COSTS_N_INSNS (2) + rtx_cost (XEXP (x, 0), code, speed);
+ if (GET_CODE (XEXP (x, 1)) != CONST_INT
+ || !const_ok_for_arm (INTVAL (XEXP (x, 1))))
+ *total += rtx_cost (XEXP (x, 1), code, speed);
+ return true;
case ABS:
- return 4 + (mode == DImode ? 4 : 0);
+ if (GET_MODE_CLASS (mode == MODE_FLOAT))
+ {
+ if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
+ {
+ *total = COSTS_N_INSNS (1);
+ return false;
+ }
+ *total = COSTS_N_INSNS (20);
+ return false;
+ }
+ *total = COSTS_N_INSNS (1);
+ if (mode == DImode)
+ *total += COSTS_N_INSNS (3);
+ return false;
case SIGN_EXTEND:
- if (arm_arch_thumb2 && mode == SImode)
- return 1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0);
+ if (GET_MODE_CLASS (mode) == MODE_INT)
+ {
+ *total = 0;
+ if (mode == DImode)
+ *total += COSTS_N_INSNS (1);
+
+ if (GET_MODE (XEXP (x, 0)) != SImode)
+ {
+ if (arm_arch6)
+ {
+ if (GET_CODE (XEXP (x, 0)) != MEM)
+ *total += COSTS_N_INSNS (1);
+ }
+ else if (!arm_arch4 || GET_CODE (XEXP (x, 0)) != MEM)
+ *total += COSTS_N_INSNS (2);
+ }
+
+ return false;
+ }
- if (GET_MODE (XEXP (x, 0)) == QImode)
- return (4 + (mode == DImode ? 4 : 0)
- + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
/* Fall through */
case ZERO_EXTEND:
- if (arm_arch6 && mode == SImode)
- return 1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0);
-
- switch (GET_MODE (XEXP (x, 0)))
+ *total = 0;
+ if (GET_MODE_CLASS (mode) == MODE_INT)
{
- case QImode:
- return (1 + (mode == DImode ? 4 : 0)
- + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
+ if (mode == DImode)
+ *total += COSTS_N_INSNS (1);
- case HImode:
- return (4 + (mode == DImode ? 4 : 0)
- + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
+ if (GET_MODE (XEXP (x, 0)) != SImode)
+ {
+ if (arm_arch6)
+ {
+ if (GET_CODE (XEXP (x, 0)) != MEM)
+ *total += COSTS_N_INSNS (1);
+ }
+ else if (!arm_arch4 || GET_CODE (XEXP (x, 0)) != MEM)
+ *total += COSTS_N_INSNS (GET_MODE (XEXP (x, 0)) == QImode ?
+ 1 : 2);
+ }
- case SImode:
- return (1 + (GET_CODE (XEXP (x, 0)) == MEM ? 10 : 0));
+ return false;
+ }
+ switch (GET_MODE (XEXP (x, 0)))
+ {
case V8QImode:
case V4HImode:
case V2SImode:
case V4QImode:
case V2HImode:
- return 1;
+ *total = COSTS_N_INSNS (1);
+ return false;
default:
gcc_unreachable ();
}
gcc_unreachable ();
+ case ZERO_EXTRACT:
+ case SIGN_EXTRACT:
+ *total = COSTS_N_INSNS (1) + rtx_cost (XEXP (x, 0), code, speed);
+ return true;
+
case CONST_INT:
- if (const_ok_for_arm (INTVAL (x)))
- return outer == SET ? 2 : -1;
- else if (outer == AND
- && const_ok_for_arm (~INTVAL (x)))
- return -1;
- else if ((outer == COMPARE
- || outer == PLUS || outer == MINUS)
- && const_ok_for_arm (-INTVAL (x)))
- return -1;
+ if (const_ok_for_arm (INTVAL (x))
+ || const_ok_for_arm (~INTVAL (x)))
+ *total = COSTS_N_INSNS (1);
else
- return 5;
+ *total = COSTS_N_INSNS (arm_gen_constant (SET, mode, NULL_RTX,
+ INTVAL (x), NULL_RTX,
+ NULL_RTX, 0, 0));
+ return true;
case CONST:
case LABEL_REF:
case SYMBOL_REF:
- return 6;
+ *total = COSTS_N_INSNS (3);
+ return true;
case HIGH:
+ *total = COSTS_N_INSNS (1);
+ return true;
+
case LO_SUM:
- return (outer == SET) ? 1 : -1;
+ *total = COSTS_N_INSNS (1);
+ *total += rtx_cost (XEXP (x, 0), code, speed);
+ return true;
case CONST_DOUBLE:
- if (arm_const_double_rtx (x) || vfp3_const_double_rtx (x))
- return outer == SET ? 2 : -1;
- else if ((outer == COMPARE || outer == PLUS)
- && neg_const_double_rtx_ok_for_fpa (x))
- return -1;
- return 7;
+ if (TARGET_HARD_FLOAT && vfp3_const_double_rtx (x))
+ *total = COSTS_N_INSNS (1);
+ else
+ *total = COSTS_N_INSNS (4);
+ return true;
default:
- return 99;
+ *total = COSTS_N_INSNS (4);
+ return false;
}
}
/* RTX costs when optimizing for size. */
static bool
-arm_size_rtx_costs (rtx x, int code, int outer_code, int *total)
+arm_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
+ int *total)
{
enum machine_mode mode = GET_MODE (x);
-
if (TARGET_THUMB1)
{
/* XXX TBD. For now, use the standard costs. */
@@ -5395,19 +5710,22 @@ arm_size_rtx_costs (rtx x, int code, int outer_code, int *total)
/* RTX costs when optimizing for size. */
static bool
-arm_rtx_costs (rtx x, int code, int outer_code, int *total, bool speed)
+arm_rtx_costs (rtx x, int code, int outer_code, int *total,
+ bool speed)
{
if (!speed)
return arm_size_rtx_costs (x, code, outer_code, total);
else
- return all_cores[(int)arm_tune].rtx_costs (x, code, outer_code, total);
+ return all_cores[(int)arm_tune].rtx_costs (x, code, outer_code, total,
+ speed);
}
/* RTX costs for cores with a slow MUL implementation. Thumb-2 is not
supported on any "slowmul" cores, so it can be ignored. */
static bool
-arm_slowmul_rtx_costs (rtx x, int code, int outer_code, int *total)
+arm_slowmul_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
+ int *total, bool speed)
{
enum machine_mode mode = GET_MODE (x);
@@ -5423,8 +5741,8 @@ arm_slowmul_rtx_costs (rtx x, int code, int outer_code, int *total)
if (GET_MODE_CLASS (mode) == MODE_FLOAT
|| mode == DImode)
{
- *total = 30;
- return true;
+ *total = COSTS_N_INSNS (20);
+ return false;
}
if (GET_CODE (XEXP (x, 1)) == CONST_INT)
@@ -5440,20 +5758,19 @@ arm_slowmul_rtx_costs (rtx x, int code, int outer_code, int *total)
for (j = 0; i && j < 32; j += booth_unit_size)
{
i >>= booth_unit_size;
- cost += 2;
+ cost++;
}
- *total = cost;
+ *total = COSTS_N_INSNS (cost);
+ *total += rtx_cost (XEXP (x, 0), code, speed);
return true;
}
- *total = 30 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4)
- + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4);
- return true;
+ *total = COSTS_N_INSNS (20);
+ return false;
default:
- *total = arm_rtx_costs_1 (x, code, outer_code);
- return true;
+ return arm_rtx_costs_1 (x, outer_code, total, speed);;
}
}
@@ -5461,7 +5778,8 @@ arm_slowmul_rtx_costs (rtx x, int code, int outer_code, int *total)
/* RTX cost for cores with a fast multiply unit (M variants). */
static bool
-arm_fastmul_rtx_costs (rtx x, int code, int outer_code, int *total)
+arm_fastmul_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
+ int *total, bool speed)
{
enum machine_mode mode = GET_MODE (x);
@@ -5482,16 +5800,15 @@ arm_fastmul_rtx_costs (rtx x, int code, int outer_code, int *total)
&& (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
|| GET_CODE (XEXP (x, 0)) == SIGN_EXTEND))
{
- *total = 8;
- return true;
+ *total = COSTS_N_INSNS(2);
+ return false;
}
- if (GET_MODE_CLASS (mode) == MODE_FLOAT
- || mode == DImode)
+ if (mode == DImode)
{
- *total = 30;
- return true;
+ *total = COSTS_N_INSNS (5);
+ return false;
}
if (GET_CODE (XEXP (x, 1)) == CONST_INT)
@@ -5507,20 +5824,34 @@ arm_fastmul_rtx_costs (rtx x, int code, int outer_code, int *total)
for (j = 0; i && j < 32; j += booth_unit_size)
{
i >>= booth_unit_size;
- cost += 2;
+ cost++;
}
- *total = cost;
- return true;
+ *total = COSTS_N_INSNS(cost);
+ return false;
}
- *total = 8 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4)
- + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4);
- return true;
+ if (mode == SImode)
+ {
+ *total = COSTS_N_INSNS (4);
+ return false;
+ }
+
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
+ {
+ *total = COSTS_N_INSNS (1);
+ return false;
+ }
+ }
+
+ /* Requires a lib call */
+ *total = COSTS_N_INSNS (20);
+ return false;
default:
- *total = arm_rtx_costs_1 (x, code, outer_code);
- return true;
+ return arm_rtx_costs_1 (x, outer_code, total, speed);
}
}
@@ -5529,7 +5860,7 @@ arm_fastmul_rtx_costs (rtx x, int code, int outer_code, int *total)
so it can be ignored. */
static bool
-arm_xscale_rtx_costs (rtx x, int code, int outer_code, int *total)
+arm_xscale_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code, int *total, bool speed)
{
enum machine_mode mode = GET_MODE (x);
@@ -5541,6 +5872,15 @@ arm_xscale_rtx_costs (rtx x, int code, int outer_code, int *total)
switch (code)
{
+ case COMPARE:
+ if (GET_CODE (XEXP (x, 0)) != MULT)
+ return arm_rtx_costs_1 (x, outer_code, total, speed);
+
+ /* A COMPARE of a MULT is slow on XScale; the muls instruction
+ will stall until the multiplication is complete. */
+ *total = COSTS_N_INSNS (3);
+ return false;
+
case MULT:
/* There is no point basing this on the tuning, since it is always the
fast variant if it exists at all. */
@@ -5549,60 +5889,58 @@ arm_xscale_rtx_costs (rtx x, int code, int outer_code, int *total)
&& (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
|| GET_CODE (XEXP (x, 0)) == SIGN_EXTEND))
{
- *total = 8;
- return true;
+ *total = COSTS_N_INSNS (2);
+ return false;
}
- if (GET_MODE_CLASS (mode) == MODE_FLOAT
- || mode == DImode)
+ if (mode == DImode)
{
- *total = 30;
- return true;
+ *total = COSTS_N_INSNS (5);
+ return false;
}
if (GET_CODE (XEXP (x, 1)) == CONST_INT)
{
- unsigned HOST_WIDE_INT i = (INTVAL (XEXP (x, 1))
- & (unsigned HOST_WIDE_INT) 0xffffffff);
- int cost, const_ok = const_ok_for_arm (i);
+ /* If operand 1 is a constant we can more accurately
+ calculate the cost of the multiply. The multiplier can
+ retire 15 bits on the first cycle and a further 12 on the
+ second. We do, of course, have to load the constant into
+ a register first. */
+ unsigned HOST_WIDE_INT i = INTVAL (XEXP (x, 1));
+ /* There's a general overhead of one cycle. */
+ int cost = 1;
unsigned HOST_WIDE_INT masked_const;
- /* The cost will be related to two insns.
- First a load of the constant (MOV or LDR), then a multiply. */
- cost = 2;
- if (! const_ok)
- cost += 1; /* LDR is probably more expensive because
- of longer result latency. */
+ if (i & 0x80000000)
+ i = ~i;
+
+ i &= (unsigned HOST_WIDE_INT) 0xffffffff;
+
masked_const = i & 0xffff8000;
- if (masked_const != 0 && masked_const != 0xffff8000)
+ if (masked_const != 0)
{
+ cost++;
masked_const = i & 0xf8000000;
- if (masked_const == 0 || masked_const == 0xf8000000)
- cost += 1;
- else
- cost += 2;
+ if (masked_const != 0)
+ cost++;
}
- *total = cost;
- return true;
+ *total = COSTS_N_INSNS (cost);
+ return false;
}
- *total = 8 + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : 4)
- + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : 4);
- return true;
+ if (mode == SImode)
+ {
+ *total = COSTS_N_INSNS (3);
+ return false;
+ }
- case COMPARE:
- /* A COMPARE of a MULT is slow on XScale; the muls instruction
- will stall until the multiplication is complete. */
- if (GET_CODE (XEXP (x, 0)) == MULT)
- *total = 4 + rtx_cost (XEXP (x, 0), code, true);
- else
- *total = arm_rtx_costs_1 (x, code, outer_code);
- return true;
+ /* Requires a lib call */
+ *total = COSTS_N_INSNS (20);
+ return false;
default:
- *total = arm_rtx_costs_1 (x, code, outer_code);
- return true;
+ return arm_rtx_costs_1 (x, outer_code, total, speed);
}
}
@@ -5610,11 +5948,10 @@ arm_xscale_rtx_costs (rtx x, int code, int outer_code, int *total)
/* RTX costs for 9e (and later) cores. */
static bool
-arm_9e_rtx_costs (rtx x, int code, int outer_code, int *total)
+arm_9e_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
+ int *total, bool speed)
{
enum machine_mode mode = GET_MODE (x);
- int nonreg_cost;
- int cost;
if (TARGET_THUMB1)
{
@@ -5640,35 +5977,37 @@ arm_9e_rtx_costs (rtx x, int code, int outer_code, int *total)
&& (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
|| GET_CODE (XEXP (x, 0)) == SIGN_EXTEND))
{
- *total = 3;
- return true;
+ *total = COSTS_N_INSNS (2);
+ return false;
}
- if (GET_MODE_CLASS (mode) == MODE_FLOAT)
- {
- *total = 30;
- return true;
- }
if (mode == DImode)
{
- cost = 7;
- nonreg_cost = 8;
+ *total = COSTS_N_INSNS (5);
+ return false;
}
- else
+
+ if (mode == SImode)
{
- cost = 2;
- nonreg_cost = 4;
+ *total = COSTS_N_INSNS (2);
+ return false;
}
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ if (TARGET_HARD_FLOAT && (mode == SFmode || mode == DFmode))
+ {
+ *total = COSTS_N_INSNS (1);
+ return false;
+ }
+ }
- *total = cost + (REG_OR_SUBREG_REG (XEXP (x, 0)) ? 0 : nonreg_cost)
- + (REG_OR_SUBREG_REG (XEXP (x, 1)) ? 0 : nonreg_cost);
- return true;
+ *total = COSTS_N_INSNS (20);
+ return false;
default:
- *total = arm_rtx_costs_1 (x, code, outer_code);
- return true;
+ return arm_rtx_costs_1 (x, outer_code, total, speed);
}
}
/* All address computations that can be done are free, but rtx cost returns
@@ -6038,7 +6377,7 @@ neon_valid_immediate (rtx op, enum machine_mode mode, int inverse,
break; \
}
- unsigned int i, elsize, idx = 0, n_elts = CONST_VECTOR_NUNITS (op);
+ unsigned int i, elsize = 0, idx = 0, n_elts = CONST_VECTOR_NUNITS (op);
unsigned int innersize = GET_MODE_SIZE (GET_MODE_INNER (mode));
unsigned char bytes[16];
int immtype = -1, matches;
@@ -10052,36 +10391,36 @@ output_move_double (rtx *operands)
}
else
{
- /* IWMMXT allows offsets larger than ldrd can handle,
- fix these up with a pair of ldr. */
- if (GET_CODE (otherops[2]) == CONST_INT
- && (INTVAL(otherops[2]) <= -256
- || INTVAL(otherops[2]) >= 256))
+ /* Use a single insn if we can.
+ FIXME: IWMMXT allows offsets larger than ldrd can
+ handle, fix these up with a pair of ldr. */
+ if (TARGET_THUMB2
+ || GET_CODE (otherops[2]) != CONST_INT
+ || (INTVAL (otherops[2]) > -256
+ && INTVAL (otherops[2]) < 256))
+ output_asm_insn ("ldr%(d%)\t%0, [%1, %2]!", otherops);
+ else
{
output_asm_insn ("ldr%?\t%0, [%1, %2]!", otherops);
- otherops[0] = gen_rtx_REG (SImode, 1 + reg0);
- output_asm_insn ("ldr%?\t%0, [%1, #4]", otherops);
+ output_asm_insn ("ldr%?\t%H0, [%1, #4]", otherops);
}
- else
- output_asm_insn ("ldr%(d%)\t%0, [%1, %2]!", otherops);
}
}
else
{
- /* IWMMXT allows offsets larger than ldrd can handle,
+ /* Use a single insn if we can.
+ FIXME: IWMMXT allows offsets larger than ldrd can handle,
fix these up with a pair of ldr. */
- if (GET_CODE (otherops[2]) == CONST_INT
- && (INTVAL(otherops[2]) <= -256
- || INTVAL(otherops[2]) >= 256))
+ if (TARGET_THUMB2
+ || GET_CODE (otherops[2]) != CONST_INT
+ || (INTVAL (otherops[2]) > -256
+ && INTVAL (otherops[2]) < 256))
+ output_asm_insn ("ldr%(d%)\t%0, [%1], %2", otherops);
+ else
{
- otherops[0] = gen_rtx_REG (SImode, 1 + reg0);
- output_asm_insn ("ldr%?\t%0, [%1, #4]", otherops);
- otherops[0] = operands[0];
+ output_asm_insn ("ldr%?\t%H0, [%1, #4]", otherops);
output_asm_insn ("ldr%?\t%0, [%1], %2", otherops);
}
- else
- /* We only allow constant increments, so this is safe. */
- output_asm_insn ("ldr%(d%)\t%0, [%1], %2", otherops);
}
break;
@@ -10135,6 +10474,7 @@ output_move_double (rtx *operands)
operands[1] = otherops[0];
if (TARGET_LDRD
&& (GET_CODE (otherops[2]) == REG
+ || TARGET_THUMB2
|| (GET_CODE (otherops[2]) == CONST_INT
&& INTVAL (otherops[2]) > -256
&& INTVAL (otherops[2]) < 256)))
@@ -10247,23 +10587,19 @@ output_move_double (rtx *operands)
/* IWMMXT allows offsets larger than ldrd can handle,
fix these up with a pair of ldr. */
- if (GET_CODE (otherops[2]) == CONST_INT
+ if (!TARGET_THUMB2
+ && GET_CODE (otherops[2]) == CONST_INT
&& (INTVAL(otherops[2]) <= -256
|| INTVAL(otherops[2]) >= 256))
{
- rtx reg1;
- reg1 = gen_rtx_REG (SImode, 1 + REGNO (operands[1]));
if (GET_CODE (XEXP (operands[0], 0)) == PRE_MODIFY)
{
output_asm_insn ("ldr%?\t%0, [%1, %2]!", otherops);
- otherops[0] = reg1;
- output_asm_insn ("ldr%?\t%0, [%1, #4]", otherops);
+ output_asm_insn ("ldr%?\t%H0, [%1, #4]", otherops);
}
else
{
- otherops[0] = reg1;
- output_asm_insn ("ldr%?\t%0, [%1, #4]", otherops);
- otherops[0] = operands[1];
+ output_asm_insn ("ldr%?\t%H0, [%1, #4]", otherops);
output_asm_insn ("ldr%?\t%0, [%1], %2", otherops);
}
}
@@ -10298,6 +10634,7 @@ output_move_double (rtx *operands)
}
if (TARGET_LDRD
&& (GET_CODE (otherops[2]) == REG
+ || TARGET_THUMB2
|| (GET_CODE (otherops[2]) == CONST_INT
&& INTVAL (otherops[2]) > -256
&& INTVAL (otherops[2]) < 256)))
@@ -10311,9 +10648,9 @@ output_move_double (rtx *operands)
default:
otherops[0] = adjust_address (operands[0], SImode, 4);
- otherops[1] = gen_rtx_REG (SImode, 1 + REGNO (operands[1]));
+ otherops[1] = operands[1];
output_asm_insn ("str%?\t%1, %0", operands);
- output_asm_insn ("str%?\t%1, %0", otherops);
+ output_asm_insn ("str%?\t%H1, %0", otherops);
}
}
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b5fea236db2..d02f5c16fae 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -10834,7 +10834,8 @@ print_operand (FILE *file, rtx x, int code)
fputs ("ord", file);
break;
default:
- gcc_unreachable ();
+ output_operand_lossage ("operand is not a condition code, invalid operand code 'D'");
+ return;
}
}
else
@@ -10872,7 +10873,8 @@ print_operand (FILE *file, rtx x, int code)
fputs ("ord", file);
break;
default:
- gcc_unreachable ();
+ output_operand_lossage ("operand is not a condition code, invalid operand code 'D'");
+ return;
}
}
return;
@@ -10894,9 +10896,23 @@ print_operand (FILE *file, rtx x, int code)
#endif
return;
case 'C':
+ if (!COMPARISON_P (x))
+ {
+ output_operand_lossage ("operand is neither a constant nor a "
+ "condition code, invalid operand code "
+ "'C'");
+ return;
+ }
put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 0, 0, file);
return;
case 'F':
+ if (!COMPARISON_P (x))
+ {
+ output_operand_lossage ("operand is neither a constant nor a "
+ "condition code, invalid operand code "
+ "'F'");
+ return;
+ }
#ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
if (ASSEMBLER_DIALECT == ASM_ATT)
putc ('.', file);
@@ -10909,13 +10925,22 @@ print_operand (FILE *file, rtx x, int code)
/* Check to see if argument to %c is really a constant
and not a condition code which needs to be reversed. */
if (!COMPARISON_P (x))
- {
- output_operand_lossage ("operand is neither a constant nor a condition code, invalid operand code 'c'");
- return;
- }
+ {
+ output_operand_lossage ("operand is neither a constant nor a "
+ "condition code, invalid operand "
+ "code 'c'");
+ return;
+ }
put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 1, 0, file);
return;
case 'f':
+ if (!COMPARISON_P (x))
+ {
+ output_operand_lossage ("operand is neither a constant nor a "
+ "condition code, invalid operand "
+ "code 'f'");
+ return;
+ }
#ifdef HAVE_AS_IX86_CMOV_SUN_SYNTAX
if (ASSEMBLER_DIALECT == ASM_ATT)
putc ('.', file);
@@ -11022,7 +11047,8 @@ print_operand (FILE *file, rtx x, int code)
fputs ("une", file);
break;
default:
- gcc_unreachable ();
+ output_operand_lossage ("operand is not a condition code, invalid operand code 'D'");
+ return;
}
return;
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7e35ecde16d..07b9c7e49e6 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,23 @@
+2009-01-15 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/38636
+ * name-lookup.c (pushtag): Don't create members to types that are not
+ being created.
+
+2009-01-14 Nick Clifton <nickc@redhat.com>
+
+ PR c++/37862
+ * parser.c: Pass cp_id_kind computed in
+ cp_parser_postfix_dot_deref_expression to
+ cp_parser_primary_expression.
+
+2009-01-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/38795
+ * tree.c (cp_walk_subtrees): Handle REINTERPRET_CAST_EXPR,
+ STATIC_CAST_EXPR, CONST_CAST_EXPR and DYNAMIC_CAST_EXPR the same
+ as CAST_EXPR.
+
2009-01-12 Jason Merrill <jason@redhat.com>
Steve Ellcey <sje@cup.hp.com>
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 6dc244fccb8..f8d0204f099 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -5109,6 +5109,9 @@ pushtag (tree name, tree type, tag_scope scope)
if (b->kind == sk_class)
{
+ if (!TYPE_BEING_DEFINED (current_class_type))
+ POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
+
if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
/* Put this TYPE_DECL on the TYPE_FIELDS list for the
class. But if it's a member template class, we want
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index bf742eea079..526a9a3acef 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1586,7 +1586,7 @@ static tree cp_parser_nested_name_specifier
static tree cp_parser_qualifying_entity
(cp_parser *, bool, bool, bool, bool, bool);
static tree cp_parser_postfix_expression
- (cp_parser *, bool, bool, bool);
+ (cp_parser *, bool, bool, bool, cp_id_kind *);
static tree cp_parser_postfix_open_square_expression
(cp_parser *, tree, bool);
static tree cp_parser_postfix_dot_deref_expression
@@ -1596,7 +1596,7 @@ static tree cp_parser_parenthesized_expression_list
static void cp_parser_pseudo_destructor_name
(cp_parser *, tree *, tree *);
static tree cp_parser_unary_expression
- (cp_parser *, bool, bool);
+ (cp_parser *, bool, bool, cp_id_kind *);
static enum tree_code cp_parser_unary_operator
(cp_token *);
static tree cp_parser_new_expression
@@ -1614,17 +1614,17 @@ static tree cp_parser_new_initializer
static tree cp_parser_delete_expression
(cp_parser *);
static tree cp_parser_cast_expression
- (cp_parser *, bool, bool);
+ (cp_parser *, bool, bool, cp_id_kind *);
static tree cp_parser_binary_expression
- (cp_parser *, bool, enum cp_parser_prec);
+ (cp_parser *, bool, enum cp_parser_prec, cp_id_kind *);
static tree cp_parser_question_colon_clause
(cp_parser *, tree);
static tree cp_parser_assignment_expression
- (cp_parser *, bool);
+ (cp_parser *, bool, cp_id_kind *);
static enum tree_code cp_parser_assignment_operator_opt
(cp_parser *);
static tree cp_parser_expression
- (cp_parser *, bool);
+ (cp_parser *, bool, cp_id_kind *);
static tree cp_parser_constant_expression
(cp_parser *, bool, bool *);
static tree cp_parser_builtin_offsetof
@@ -3251,7 +3251,7 @@ cp_parser_primary_expression (cp_parser *parser,
else
{
/* Parse the parenthesized expression. */
- expr = cp_parser_expression (parser, cast_p);
+ expr = cp_parser_expression (parser, cast_p, idk);
/* Let the front end know that this expression was
enclosed in parentheses. This matters in case, for
example, the expression is of the form `A::B', since
@@ -3354,7 +3354,7 @@ cp_parser_primary_expression (cp_parser *parser,
cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
/* Now, parse the assignment-expression. */
expression = cp_parser_assignment_expression (parser,
- /*cast_p=*/false);
+ /*cast_p=*/false, NULL);
/* Look for the `,'. */
cp_parser_require (parser, CPP_COMMA, "%<,%>");
/* Parse the type-id. */
@@ -4399,7 +4399,8 @@ cp_parser_qualifying_entity (cp_parser *parser,
static tree
cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
- bool member_access_only_p)
+ bool member_access_only_p,
+ cp_id_kind * pidk_return)
{
cp_token *token;
enum rid keyword;
@@ -4443,7 +4444,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
/* And the expression which is being cast. */
cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
- expression = cp_parser_expression (parser, /*cast_p=*/true);
+ expression = cp_parser_expression (parser, /*cast_p=*/true, & idk);
cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
/* Only type conversions to integral or enumeration types
@@ -4515,7 +4516,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
tree expression;
/* Look for an expression. */
- expression = cp_parser_expression (parser, /*cast_p=*/false);
+ expression = cp_parser_expression (parser, /*cast_p=*/false, & idk);
/* Compute its typeid. */
postfix_expression = build_typeid (expression);
/* Look for the `)' token. */
@@ -4767,6 +4768,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
}
if (BASELINK_P (fn))
+ {
postfix_expression
= (build_new_method_call
(instance, fn, args, NULL_TREE,
@@ -4774,6 +4776,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
? LOOKUP_NONVIRTUAL : LOOKUP_NORMAL),
/*fn_p=*/NULL,
tf_warning_or_error));
+ }
else
postfix_expression
= finish_call_expr (postfix_expression, args,
@@ -4862,6 +4865,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
break;
default:
+ if (pidk_return != NULL)
+ * pidk_return = idk;
if (member_access_only_p)
return is_member_access? postfix_expression : error_mark_node;
else
@@ -4903,7 +4908,7 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
if (for_offsetof)
index = cp_parser_constant_expression (parser, false, NULL);
else
- index = cp_parser_expression (parser, /*cast_p=*/false);
+ index = cp_parser_expression (parser, /*cast_p=*/false, NULL);
/* Look for the closing `]'. */
cp_parser_require (parser, CPP_CLOSE_SQUARE, "%<]%>");
@@ -4956,6 +4961,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
parser->qualifying_scope = NULL_TREE;
parser->object_scope = NULL_TREE;
*idk = CP_ID_KIND_NONE;
+
/* Enter the scope corresponding to the type of the object
given by the POSTFIX_EXPRESSION. */
if (!dependent_p && TREE_TYPE (postfix_expression) != NULL_TREE)
@@ -5185,7 +5191,7 @@ cp_parser_parenthesized_expression_list (cp_parser* parser,
*non_constant_p = true;
}
else
- expr = cp_parser_assignment_expression (parser, cast_p);
+ expr = cp_parser_assignment_expression (parser, cast_p, NULL);
if (fold_expr_p)
expr = fold_non_dependent_expr (expr);
@@ -5369,7 +5375,8 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
Returns a representation of the expression. */
static tree
-cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p)
+cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
+ cp_id_kind * pidk)
{
cp_token *token;
enum tree_code unary_operator;
@@ -5506,7 +5513,7 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p)
cast_expression
= cp_parser_cast_expression (parser,
unary_operator == ADDR_EXPR,
- /*cast_p=*/false);
+ /*cast_p=*/false, pidk);
/* Now, build an appropriate representation. */
switch (unary_operator)
{
@@ -5548,7 +5555,8 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p)
}
return cp_parser_postfix_expression (parser, address_p, cast_p,
- /*member_access_only_p=*/false);
+ /*member_access_only_p=*/false,
+ pidk);
}
/* Returns ERROR_MARK if TOKEN is not a unary-operator. If TOKEN is a
@@ -5813,7 +5821,7 @@ cp_parser_direct_new_declarator (cp_parser* parser)
if (!declarator)
{
cp_token *token = cp_lexer_peek_token (parser->lexer);
- expression = cp_parser_expression (parser, /*cast_p=*/false);
+ expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
/* The standard requires that the expression have integral
type. DR 74 adds enumeration types. We believe that the
real intent is that these expressions be handled like the
@@ -6001,7 +6009,8 @@ cp_parser_token_starts_cast_expression (cp_token *token)
Returns a representation of the expression. */
static tree
-cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
+cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
+ cp_id_kind * pidk)
{
/* If it's a `(', then we might be looking at a cast. */
if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
@@ -6076,7 +6085,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
cp_parser_parse_definitely (parser);
expr = cp_parser_cast_expression (parser,
/*address_p=*/false,
- /*cast_p=*/true);
+ /*cast_p=*/true, pidk);
/* Warn about old-style casts, if so requested. */
if (warn_old_style_cast
@@ -6104,7 +6113,7 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
/* If we get here, then it's not a cast, so it must be a
unary-expression. */
- return cp_parser_unary_expression (parser, address_p, cast_p);
+ return cp_parser_unary_expression (parser, address_p, cast_p, pidk);
}
/* Parse a binary expression of the general form:
@@ -6188,7 +6197,8 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p)
static tree
cp_parser_binary_expression (cp_parser* parser, bool cast_p,
- enum cp_parser_prec prec)
+ enum cp_parser_prec prec,
+ cp_id_kind * pidk)
{
cp_parser_expression_stack stack;
cp_parser_expression_stack_entry *sp = &stack[0];
@@ -6199,7 +6209,7 @@ cp_parser_binary_expression (cp_parser* parser, bool cast_p,
bool overloaded_p;
/* Parse the first expression. */
- lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p);
+ lhs = cp_parser_cast_expression (parser, /*address_p=*/false, cast_p, pidk);
lhs_type = ERROR_MARK;
for (;;)
@@ -6340,12 +6350,12 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
expr = NULL_TREE;
else
/* Parse the expression. */
- expr = cp_parser_expression (parser, /*cast_p=*/false);
+ expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
/* The next token should be a `:'. */
cp_parser_require (parser, CPP_COLON, "%<:%>");
/* Parse the assignment-expression. */
- assignment_expr = cp_parser_assignment_expression (parser, /*cast_p=*/false);
+ assignment_expr = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
/* Build the conditional-expression. */
return build_x_conditional_expr (logical_or_expr,
@@ -6366,7 +6376,8 @@ cp_parser_question_colon_clause (cp_parser* parser, tree logical_or_expr)
Returns a representation for the expression. */
static tree
-cp_parser_assignment_expression (cp_parser* parser, bool cast_p)
+cp_parser_assignment_expression (cp_parser* parser, bool cast_p,
+ cp_id_kind * pidk)
{
tree expr;
@@ -6379,7 +6390,7 @@ cp_parser_assignment_expression (cp_parser* parser, bool cast_p)
else
{
/* Parse the binary expressions (logical-or-expression). */
- expr = cp_parser_binary_expression (parser, cast_p, PREC_NOT_OPERATOR);
+ expr = cp_parser_binary_expression (parser, cast_p, PREC_NOT_OPERATOR, pidk);
/* If the next token is a `?' then we're actually looking at a
conditional-expression. */
if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY))
@@ -6514,7 +6525,7 @@ cp_parser_assignment_operator_opt (cp_parser* parser)
Returns a representation of the expression. */
static tree
-cp_parser_expression (cp_parser* parser, bool cast_p)
+cp_parser_expression (cp_parser* parser, bool cast_p, cp_id_kind * pidk)
{
tree expression = NULL_TREE;
@@ -6524,7 +6535,7 @@ cp_parser_expression (cp_parser* parser, bool cast_p)
/* Parse the next assignment-expression. */
assignment_expression
- = cp_parser_assignment_expression (parser, cast_p);
+ = cp_parser_assignment_expression (parser, cast_p, pidk);
/* If this is the first assignment-expression, we can just
save it away. */
if (!expression)
@@ -6603,7 +6614,7 @@ cp_parser_constant_expression (cp_parser* parser,
For example, cp_parser_initializer_clauses uses this function to
determine whether a particular assignment-expression is in fact
constant. */
- expression = cp_parser_assignment_expression (parser, /*cast_p=*/false);
+ expression = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
/* Restore the old settings. */
parser->integral_constant_expression_p
= saved_integral_constant_expression_p;
@@ -7086,7 +7097,7 @@ cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr)
/* If the next token is a ';', then there is no expression
statement. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
- statement = cp_parser_expression (parser, /*cast_p=*/false);
+ statement = cp_parser_expression (parser, /*cast_p=*/false, NULL);
/* Consume the final `;'. */
cp_parser_consume_semicolon_at_end_of_statement (parser);
@@ -7454,7 +7465,7 @@ cp_parser_condition (cp_parser* parser)
cp_parser_abort_tentative_parse (parser);
/* Otherwise, we are looking at an expression. */
- return cp_parser_expression (parser, /*cast_p=*/false);
+ return cp_parser_expression (parser, /*cast_p=*/false, NULL);
}
/* Parse an iteration-statement.
@@ -7526,7 +7537,7 @@ cp_parser_iteration_statement (cp_parser* parser)
/* Look for the `('. */
cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
/* Parse the expression. */
- expression = cp_parser_expression (parser, /*cast_p=*/false);
+ expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
/* We're done with the do-statement. */
finish_do_stmt (expression, statement);
/* Look for the `)'. */
@@ -7558,7 +7569,7 @@ cp_parser_iteration_statement (cp_parser* parser)
/* If there's an expression, process it. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
- expression = cp_parser_expression (parser, /*cast_p=*/false);
+ expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
finish_for_expr (expression, statement);
/* Look for the `)'. */
cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
@@ -7699,7 +7710,7 @@ cp_parser_jump_statement (cp_parser* parser)
expr = cp_parser_braced_list (parser, &expr_non_constant_p);
}
else if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
- expr = cp_parser_expression (parser, /*cast_p=*/false);
+ expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
else
/* If the next token is a `;', then there is no
expression. */
@@ -7720,7 +7731,7 @@ cp_parser_jump_statement (cp_parser* parser)
/* Consume the '*' token. */
cp_lexer_consume_token (parser->lexer);
/* Parse the dependent expression. */
- finish_goto_stmt (cp_parser_expression (parser, /*cast_p=*/false));
+ finish_goto_stmt (cp_parser_expression (parser, /*cast_p=*/false, NULL));
}
else
finish_goto_stmt (cp_parser_identifier (parser));
@@ -8857,7 +8868,7 @@ cp_parser_decltype (cp_parser *parser)
/* Parse a class member access. */
expr = cp_parser_postfix_expression (parser, /*address_p=*/false,
/*cast_p=*/false,
- /*member_access_only_p=*/true);
+ /*member_access_only_p=*/true, NULL);
if (expr
&& expr != error_mark_node
@@ -8876,7 +8887,7 @@ cp_parser_decltype (cp_parser *parser)
cp_parser_abort_tentative_parse (parser);
/* Parse a full expression. */
- expr = cp_parser_expression (parser, /*cast_p=*/false);
+ expr = cp_parser_expression (parser, /*cast_p=*/false, NULL);
}
/* Go back to evaluating expressions. */
@@ -14424,7 +14435,7 @@ cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
if (template_parm_p)
push_deferring_access_checks (dk_no_deferred);
default_argument
- = cp_parser_assignment_expression (parser, /*cast_p=*/false);
+ = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
if (template_parm_p)
pop_deferring_access_checks ();
/* Restore saved state. */
@@ -16512,7 +16523,7 @@ cp_parser_throw_expression (cp_parser* parser)
expression = NULL_TREE;
else
expression = cp_parser_assignment_expression (parser,
- /*cast_p=*/false);
+ /*cast_p=*/false, NULL);
return build_throw (expression);
}
@@ -16604,7 +16615,7 @@ cp_parser_asm_operand_list (cp_parser* parser)
/* Look for the `('. */
cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
/* Parse the expression. */
- expression = cp_parser_expression (parser, /*cast_p=*/false);
+ expression = cp_parser_expression (parser, /*cast_p=*/false, NULL);
/* Look for the `)'. */
cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
@@ -17875,7 +17886,7 @@ static tree
cp_parser_simple_cast_expression (cp_parser *parser)
{
return cp_parser_cast_expression (parser, /*address_p=*/false,
- /*cast_p=*/false);
+ /*cast_p=*/false, NULL);
}
/* Parse a functional cast to TYPE. Returns an expression
@@ -18241,7 +18252,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
cp_parser_push_lexer_for_tokens (parser, tokens);
/* Parse the assignment-expression. */
- parsed_arg = cp_parser_assignment_expression (parser, /*cast_p=*/false);
+ parsed_arg = cp_parser_assignment_expression (parser, /*cast_p=*/false, NULL);
if (!processing_template_decl)
parsed_arg = check_default_argument (TREE_VALUE (parm), parsed_arg);
@@ -18362,7 +18373,7 @@ cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
looking at the unary-expression production. */
if (!expr)
expr = cp_parser_unary_expression (parser, /*address_p=*/false,
- /*cast_p=*/false);
+ /*cast_p=*/false, NULL);
if (pack_expansion_p)
/* Build a pack expansion. */
@@ -19090,7 +19101,7 @@ cp_parser_objc_message_receiver (cp_parser* parser)
/* An Objective-C message receiver may be either (1) a type
or (2) an expression. */
cp_parser_parse_tentatively (parser);
- rcv = cp_parser_expression (parser, false);
+ rcv = cp_parser_expression (parser, false, NULL);
if (cp_parser_parse_definitely (parser))
return rcv;
@@ -19142,7 +19153,7 @@ cp_parser_objc_message_args (cp_parser* parser)
maybe_unary_selector_p = false;
cp_parser_require (parser, CPP_COLON, "%<:%>");
- arg = cp_parser_assignment_expression (parser, false);
+ arg = cp_parser_assignment_expression (parser, false, NULL);
sel_args
= chainon (sel_args,
@@ -19157,7 +19168,7 @@ cp_parser_objc_message_args (cp_parser* parser)
tree arg;
cp_lexer_consume_token (parser->lexer);
- arg = cp_parser_assignment_expression (parser, false);
+ arg = cp_parser_assignment_expression (parser, false, NULL);
addl_args
= chainon (addl_args,
@@ -20057,7 +20068,7 @@ cp_parser_objc_synchronized_statement (cp_parser *parser) {
location = cp_lexer_peek_token (parser->lexer)->location;
cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>");
- lock = cp_parser_expression (parser, false);
+ lock = cp_parser_expression (parser, false, NULL);
cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>");
/* NB: The @synchronized block needs to be wrapped in its own STATEMENT_LIST
@@ -20082,7 +20093,7 @@ cp_parser_objc_throw_statement (cp_parser *parser) {
cp_parser_require_keyword (parser, RID_AT_THROW, "%<@throw%>");
if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
- expr = cp_parser_assignment_expression (parser, false);
+ expr = cp_parser_assignment_expression (parser, false, NULL);
cp_parser_consume_semicolon_at_end_of_statement (parser);
@@ -20439,7 +20450,7 @@ cp_parser_omp_clause_num_threads (cp_parser *parser, tree list,
if (!cp_parser_require (parser, CPP_OPEN_PAREN, "%<(%>"))
return list;
- t = cp_parser_expression (parser, false);
+ t = cp_parser_expression (parser, false, NULL);
if (t == error_mark_node
|| !cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
@@ -20596,7 +20607,7 @@ cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location
cp_lexer_consume_token (parser->lexer);
token = cp_lexer_peek_token (parser->lexer);
- t = cp_parser_assignment_expression (parser, false);
+ t = cp_parser_assignment_expression (parser, false, NULL);
if (t == error_mark_node)
goto resync_fail;
@@ -20825,7 +20836,7 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
cp_parser_require_pragma_eol (parser, pragma_tok);
lhs = cp_parser_unary_expression (parser, /*address_p=*/false,
- /*cast_p=*/false);
+ /*cast_p=*/false, NULL);
switch (TREE_CODE (lhs))
{
case ERROR_MARK:
@@ -20882,7 +20893,7 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
}
cp_lexer_consume_token (parser->lexer);
- rhs = cp_parser_expression (parser, false);
+ rhs = cp_parser_expression (parser, false, NULL);
if (rhs == error_mark_node)
goto saw_error;
break;
@@ -20956,7 +20967,7 @@ cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok)
static tree
cp_parser_omp_for_cond (cp_parser *parser, tree decl)
{
- tree lhs = cp_parser_cast_expression (parser, false, false), rhs;
+ tree lhs = cp_parser_cast_expression (parser, false, false, NULL), rhs;
enum tree_code op;
cp_token *token;
@@ -20982,7 +20993,7 @@ cp_parser_omp_for_cond (cp_parser *parser, tree decl)
cp_lexer_consume_token (parser->lexer);
rhs = cp_parser_binary_expression (parser, false,
- PREC_RELATIONAL_EXPRESSION);
+ PREC_RELATIONAL_EXPRESSION, NULL);
if (rhs == error_mark_node
|| cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
{
@@ -21009,7 +21020,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
op = (token->type == CPP_PLUS_PLUS
? PREINCREMENT_EXPR : PREDECREMENT_EXPR);
cp_lexer_consume_token (parser->lexer);
- lhs = cp_parser_cast_expression (parser, false, false);
+ lhs = cp_parser_cast_expression (parser, false, false, NULL);
if (lhs != decl)
return error_mark_node;
return build2 (op, TREE_TYPE (decl), decl, NULL_TREE);
@@ -21034,13 +21045,13 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
if (op != NOP_EXPR)
{
- rhs = cp_parser_assignment_expression (parser, false);
+ rhs = cp_parser_assignment_expression (parser, false, NULL);
rhs = build2 (op, TREE_TYPE (decl), decl, rhs);
return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs);
}
lhs = cp_parser_binary_expression (parser, false,
- PREC_ADDITIVE_EXPRESSION);
+ PREC_ADDITIVE_EXPRESSION, NULL);
token = cp_lexer_peek_token (parser->lexer);
decl_first = lhs == decl;
if (decl_first)
@@ -21054,7 +21065,7 @@ cp_parser_omp_for_incr (cp_parser *parser, tree decl)
op = token->type == CPP_PLUS ? PLUS_EXPR : MINUS_EXPR;
cp_lexer_consume_token (parser->lexer);
rhs = cp_parser_binary_expression (parser, false,
- PREC_ADDITIVE_EXPRESSION);
+ PREC_ADDITIVE_EXPRESSION, NULL);
token = cp_lexer_peek_token (parser->lexer);
if (token->type == CPP_PLUS || token->type == CPP_MINUS || decl_first)
{
@@ -21224,7 +21235,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
{
/* Consume '='. */
cp_lexer_consume_token (parser->lexer);
- init = cp_parser_assignment_expression (parser, false);
+ init = cp_parser_assignment_expression (parser, false, NULL);
non_class:
if (TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE)
@@ -21257,7 +21268,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
cp_parser_parse_definitely (parser);
cp_parser_require (parser, CPP_EQ, "%<=%>");
- rhs = cp_parser_assignment_expression (parser, false);
+ rhs = cp_parser_assignment_expression (parser, false, NULL);
finish_expr_stmt (build_x_modify_expr (decl, NOP_EXPR,
rhs,
tf_warning_or_error));
@@ -21267,7 +21278,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
{
decl = NULL;
cp_parser_abort_tentative_parse (parser);
- init = cp_parser_expression (parser, false);
+ init = cp_parser_expression (parser, false, NULL);
if (init)
{
if (TREE_CODE (init) == MODIFY_EXPR
@@ -21384,7 +21395,7 @@ cp_parser_omp_for_loop (cp_parser *parser, tree clauses, tree *par_clauses)
|| CLASS_TYPE_P (TREE_TYPE (decl))))
incr = cp_parser_omp_for_incr (parser, decl);
else
- incr = cp_parser_expression (parser, false);
+ incr = cp_parser_expression (parser, false, NULL);
}
if (!cp_parser_require (parser, CPP_CLOSE_PAREN, "%<)%>"))
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index ad84cc8d8d3..8ac272095be 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1,6 +1,6 @@
/* Language-dependent node constructors for parse phase of GNU compiler.
Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
@@ -2443,6 +2443,10 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
break;
case CAST_EXPR:
+ case REINTERPRET_CAST_EXPR:
+ case STATIC_CAST_EXPR:
+ case CONST_CAST_EXPR:
+ case DYNAMIC_CAST_EXPR:
if (TREE_TYPE (*tp))
WALK_SUBTREE (TREE_TYPE (*tp));
diff --git a/gcc/dce.c b/gcc/dce.c
index 08a0f5048e3..75e148cf434 100644
--- a/gcc/dce.c
+++ b/gcc/dce.c
@@ -1,5 +1,5 @@
/* RTL dead code elimination.
- Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
This file is part of GCC.
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "timevar.h"
#include "tree-pass.h"
#include "dbgcnt.h"
+#include "tm_p.h"
DEF_VEC_I(int);
DEF_VEC_ALLOC_I(int,heap);
@@ -57,6 +58,7 @@ static sbitmap marked;
static bitmap_obstack dce_blocks_bitmap_obstack;
static bitmap_obstack dce_tmp_bitmap_obstack;
+static bool find_call_stack_args (rtx, bool, bool, bitmap);
/* A subroutine for which BODY is part of the instruction being tested;
either the top-level pattern, or an element of a PARALLEL. The
@@ -94,7 +96,7 @@ deletable_insn_p_1 (rtx body)
the DCE pass. */
static bool
-deletable_insn_p (rtx insn, bool fast)
+deletable_insn_p (rtx insn, bool fast, bitmap arg_stores)
{
rtx body, x;
int i;
@@ -111,7 +113,7 @@ deletable_insn_p (rtx insn, bool fast)
infinite loop. */
&& (RTL_CONST_OR_PURE_CALL_P (insn)
&& !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)))
- return true;
+ return find_call_stack_args (insn, false, fast, arg_stores);
if (!NONJUMP_INSN_P (insn))
return false;
@@ -174,6 +176,12 @@ mark_insn (rtx insn, bool fast)
SET_BIT (marked, INSN_UID (insn));
if (dump_file)
fprintf (dump_file, " Adding insn %d to worklist\n", INSN_UID (insn));
+ if (CALL_P (insn)
+ && !df_in_progress
+ && !SIBLING_CALL_P (insn)
+ && (RTL_CONST_OR_PURE_CALL_P (insn)
+ && !RTL_LOOPING_CONST_OR_PURE_CALL_P (insn)))
+ find_call_stack_args (insn, true, fast, NULL);
}
}
@@ -212,6 +220,254 @@ mark_nonreg_stores (rtx body, rtx insn, bool fast)
}
+/* Try to find all stack stores of CALL_INSN arguments if
+ ACCUMULATE_OUTGOING_ARGS. If all stack stores have been found
+ and it is therefore safe to eliminate the call, return true,
+ otherwise return false. This function should be first called
+ with DO_MARK false, and only when the CALL_INSN is actually
+ going to be marked called again with DO_MARK true. */
+
+static bool
+find_call_stack_args (rtx call_insn, bool do_mark, bool fast,
+ bitmap arg_stores)
+{
+ rtx p, insn, prev_insn;
+ bool ret;
+ HOST_WIDE_INT min_sp_off, max_sp_off;
+ bitmap sp_bytes;
+
+ gcc_assert (CALL_P (call_insn));
+ if (!ACCUMULATE_OUTGOING_ARGS)
+ return true;
+
+ if (!do_mark)
+ {
+ gcc_assert (arg_stores);
+ bitmap_clear (arg_stores);
+ }
+
+ min_sp_off = INTTYPE_MAXIMUM (HOST_WIDE_INT);
+ max_sp_off = 0;
+
+ /* First determine the minimum and maximum offset from sp for
+ stored arguments. */
+ for (p = CALL_INSN_FUNCTION_USAGE (call_insn); p; p = XEXP (p, 1))
+ if (GET_CODE (XEXP (p, 0)) == USE
+ && MEM_P (XEXP (XEXP (p, 0), 0)))
+ {
+ rtx mem = XEXP (XEXP (p, 0), 0), addr, size;
+ HOST_WIDE_INT off = 0;
+ size = MEM_SIZE (mem);
+ if (size == NULL_RTX)
+ return false;
+ addr = XEXP (mem, 0);
+ if (GET_CODE (addr) == PLUS
+ && REG_P (XEXP (addr, 0))
+ && CONST_INT_P (XEXP (addr, 1)))
+ {
+ off = INTVAL (XEXP (addr, 1));
+ addr = XEXP (addr, 0);
+ }
+ if (addr != stack_pointer_rtx)
+ {
+ if (!REG_P (addr))
+ return false;
+ /* If not fast, use chains to see if addr wasn't set to
+ sp + offset. */
+ if (!fast)
+ {
+ df_ref *use_rec;
+ struct df_link *defs;
+ rtx set;
+
+ for (use_rec = DF_INSN_USES (call_insn); *use_rec; use_rec++)
+ if (rtx_equal_p (addr, DF_REF_REG (*use_rec)))
+ break;
+
+ if (*use_rec == NULL)
+ return false;
+
+ for (defs = DF_REF_CHAIN (*use_rec); defs; defs = defs->next)
+ if (! DF_REF_IS_ARTIFICIAL (defs->ref))
+ break;
+
+ if (defs == NULL)
+ return false;
+
+ set = single_set (DF_REF_INSN (defs->ref));
+ if (!set)
+ return false;
+
+ if (GET_CODE (SET_SRC (set)) != PLUS
+ || XEXP (SET_SRC (set), 0) != stack_pointer_rtx
+ || !CONST_INT_P (XEXP (SET_SRC (set), 1)))
+ return false;
+
+ off += INTVAL (XEXP (SET_SRC (set), 1));
+ }
+ else
+ return false;
+ }
+ min_sp_off = MIN (min_sp_off, off);
+ max_sp_off = MAX (max_sp_off, off + INTVAL (size));
+ }
+
+ if (min_sp_off >= max_sp_off)
+ return true;
+ sp_bytes = BITMAP_ALLOC (NULL);
+
+ /* Set bits in SP_BYTES bitmap for bytes relative to sp + min_sp_off
+ which contain arguments. Checking has been done in the previous
+ loop. */
+ for (p = CALL_INSN_FUNCTION_USAGE (call_insn); p; p = XEXP (p, 1))
+ if (GET_CODE (XEXP (p, 0)) == USE
+ && MEM_P (XEXP (XEXP (p, 0), 0)))
+ {
+ rtx mem = XEXP (XEXP (p, 0), 0), addr;
+ HOST_WIDE_INT off = 0, byte;
+ addr = XEXP (mem, 0);
+ if (GET_CODE (addr) == PLUS
+ && REG_P (XEXP (addr, 0))
+ && CONST_INT_P (XEXP (addr, 1)))
+ {
+ off = INTVAL (XEXP (addr, 1));
+ addr = XEXP (addr, 0);
+ }
+ if (addr != stack_pointer_rtx)
+ {
+ df_ref *use_rec;
+ struct df_link *defs;
+ rtx set;
+
+ for (use_rec = DF_INSN_USES (call_insn); *use_rec; use_rec++)
+ if (rtx_equal_p (addr, DF_REF_REG (*use_rec)))
+ break;
+
+ for (defs = DF_REF_CHAIN (*use_rec); defs; defs = defs->next)
+ if (! DF_REF_IS_ARTIFICIAL (defs->ref))
+ break;
+
+ set = single_set (DF_REF_INSN (defs->ref));
+ off += INTVAL (XEXP (SET_SRC (set), 1));
+ }
+ for (byte = off; byte < off + INTVAL (MEM_SIZE (mem)); byte++)
+ {
+ gcc_assert (!bitmap_bit_p (sp_bytes, byte - min_sp_off));
+ bitmap_set_bit (sp_bytes, byte - min_sp_off);
+ }
+ }
+
+ /* Walk backwards, looking for argument stores. The search stops
+ when seeting another call, sp adjustment or memory store other than
+ argument store. */
+ ret = false;
+ for (insn = PREV_INSN (call_insn); insn; insn = prev_insn)
+ {
+ rtx set, mem, addr;
+ HOST_WIDE_INT off, byte;
+
+ if (insn == BB_HEAD (BLOCK_FOR_INSN (call_insn)))
+ prev_insn = NULL_RTX;
+ else
+ prev_insn = PREV_INSN (insn);
+
+ if (CALL_P (insn))
+ break;
+
+ if (!INSN_P (insn))
+ continue;
+
+ set = single_set (insn);
+ if (!set || SET_DEST (set) == stack_pointer_rtx)
+ break;
+
+ if (!MEM_P (SET_DEST (set)))
+ continue;
+
+ mem = SET_DEST (set);
+ addr = XEXP (mem, 0);
+ off = 0;
+ if (GET_CODE (addr) == PLUS
+ && REG_P (XEXP (addr, 0))
+ && CONST_INT_P (XEXP (addr, 1)))
+ {
+ off = INTVAL (XEXP (addr, 1));
+ addr = XEXP (addr, 0);
+ }
+ if (addr != stack_pointer_rtx)
+ {
+ if (!REG_P (addr))
+ break;
+ if (!fast)
+ {
+ df_ref *use_rec;
+ struct df_link *defs;
+ rtx set;
+
+ for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++)
+ if (rtx_equal_p (addr, DF_REF_REG (*use_rec)))
+ break;
+
+ if (*use_rec == NULL)
+ break;
+
+ for (defs = DF_REF_CHAIN (*use_rec); defs; defs = defs->next)
+ if (! DF_REF_IS_ARTIFICIAL (defs->ref))
+ break;
+
+ if (defs == NULL)
+ break;
+
+ set = single_set (DF_REF_INSN (defs->ref));
+ if (!set)
+ break;
+
+ if (GET_CODE (SET_SRC (set)) != PLUS
+ || XEXP (SET_SRC (set), 0) != stack_pointer_rtx
+ || !CONST_INT_P (XEXP (SET_SRC (set), 1)))
+ break;
+
+ off += INTVAL (XEXP (SET_SRC (set), 1));
+ }
+ else
+ break;
+ }
+
+ if (GET_MODE_SIZE (GET_MODE (mem)) == 0)
+ break;
+
+ for (byte = off; byte < off + GET_MODE_SIZE (GET_MODE (mem)); byte++)
+ {
+ if (byte < min_sp_off
+ || byte >= max_sp_off
+ || !bitmap_bit_p (sp_bytes, byte - min_sp_off))
+ break;
+ bitmap_clear_bit (sp_bytes, byte - min_sp_off);
+ }
+
+ if (!deletable_insn_p (insn, fast, NULL))
+ break;
+
+ if (do_mark)
+ mark_insn (insn, fast);
+ else
+ bitmap_set_bit (arg_stores, INSN_UID (insn));
+
+ if (bitmap_empty_p (sp_bytes))
+ {
+ ret = true;
+ break;
+ }
+ }
+
+ BITMAP_FREE (sp_bytes);
+ if (!ret && arg_stores)
+ bitmap_clear (arg_stores);
+
+ return ret;
+}
+
+
/* Delete all REG_EQUAL notes of the registers INSN writes, to prevent
bad dangling REG_EQUAL notes. */
@@ -266,6 +522,9 @@ delete_unmarked_insns (void)
else if (marked_insn_p (insn))
continue;
+ /* Beware that reaching a dbg counter limit here can easily result
+ in miscompiled file, whenever some insn is eliminated, but
+ insn that depends on it is not. */
if (!dbg_cnt (dce))
continue;
@@ -300,20 +559,37 @@ static void
prescan_insns_for_dce (bool fast)
{
basic_block bb;
- rtx insn, next;
-
+ rtx insn, prev;
+ bitmap arg_stores = NULL;
+
if (dump_file)
fprintf (dump_file, "Finding needed instructions:\n");
-
+
+ if (!df_in_progress && ACCUMULATE_OUTGOING_ARGS)
+ arg_stores = BITMAP_ALLOC (NULL);
+
FOR_EACH_BB (bb)
- FOR_BB_INSNS_SAFE (bb, insn, next)
- if (INSN_P (insn))
- {
- if (deletable_insn_p (insn, fast))
- mark_nonreg_stores (PATTERN (insn), insn, fast);
- else
- mark_insn (insn, fast);
- }
+ {
+ FOR_BB_INSNS_REVERSE_SAFE (bb, insn, prev)
+ if (INSN_P (insn))
+ {
+ /* Don't mark argument stores now. They will be marked
+ if needed when the associated CALL is marked. */
+ if (arg_stores && bitmap_bit_p (arg_stores, INSN_UID (insn)))
+ continue;
+ if (deletable_insn_p (insn, fast, arg_stores))
+ mark_nonreg_stores (PATTERN (insn), insn, fast);
+ else
+ mark_insn (insn, fast);
+ }
+ /* find_call_stack_args only looks at argument stores in the
+ same bb. */
+ if (arg_stores)
+ bitmap_clear (arg_stores);
+ }
+
+ if (arg_stores)
+ BITMAP_FREE (arg_stores);
if (dump_file)
fprintf (dump_file, "Finished finding needed instructions:\n");
diff --git a/gcc/doc/gty.texi b/gcc/doc/gty.texi
index 17936146a2e..c5c0f9ed051 100644
--- a/gcc/doc/gty.texi
+++ b/gcc/doc/gty.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 2002, 2003, 2004, 2007, 2008
+@c Copyright (C) 2002, 2003, 2004, 2007, 2008, 2009
@c Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -69,6 +69,7 @@ These don't need to be marked.
* GTY Options:: What goes inside a @code{GTY(())}.
* GGC Roots:: Making global variables GGC roots.
* Files:: How the generated files work.
+* Invoking the garbage collector:: How to invoke the garbage collector.
@end menu
@node GTY Options
@@ -448,3 +449,22 @@ source file. Don't forget to mention this file as a dependency in the
For language frontends, there is another file that needs to be included
somewhere. It will be called @file{gtype-@var{lang}.h}, where
@var{lang} is the name of the subdirectory the language is contained in.
+
+@node Invoking the garbage collector
+@section How to invoke the garbage collector
+@cindex garbage collector, invocation
+@findex ggc_collect
+
+The GCC garbage collector GGC is only invoked explicitly. In contrast
+with many other garbage collectors, it is not implicitly invoked by
+allocation routines when a lot of memory has been consumed. So the
+only way to have GGC reclaim storage it to call the @code{ggc_collect}
+function explicitly. This call is an expensive operation, as it may
+have to scan the entire heap. Beware that local variables (on the GCC
+call stack) are not followed by such an invocation (as many other
+garbage collectors do): you should reference all your data from static
+or external @code{GTY}-ed variables, and it is advised to call
+@code{ggc_collect} with a shallow call stack. The GGC is an exact mark
+and sweep garbage collector (so it does not scan the call stack for
+pointers). In practice GCC passes don't often call @code{ggc_collect}
+themselves, because it is called by the pass manager between passes.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 850d017fb16..9f96120bd60 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -8878,8 +8878,11 @@ assembly code. Permissible names are: @samp{arm2}, @samp{arm250},
@samp{arm620}, @samp{arm7}, @samp{arm7m}, @samp{arm7d}, @samp{arm7dm},
@samp{arm7di}, @samp{arm7dmi}, @samp{arm70}, @samp{arm700},
@samp{arm700i}, @samp{arm710}, @samp{arm710c}, @samp{arm7100},
+@samp{arm720},
@samp{arm7500}, @samp{arm7500fe}, @samp{arm7tdmi}, @samp{arm7tdmi-s},
-@samp{arm8}, @samp{strongarm}, @samp{strongarm110}, @samp{strongarm1100},
+@samp{arm710t}, @samp{arm720t}, @samp{arm740t},
+@samp{strongarm}, @samp{strongarm110}, @samp{strongarm1100},
+@samp{strongarm1110},
@samp{arm8}, @samp{arm810}, @samp{arm9}, @samp{arm9e}, @samp{arm920},
@samp{arm920t}, @samp{arm922t}, @samp{arm946e-s}, @samp{arm966e-s},
@samp{arm968e-s}, @samp{arm926ej-s}, @samp{arm940t}, @samp{arm9tdmi},
@@ -8887,7 +8890,8 @@ assembly code. Permissible names are: @samp{arm2}, @samp{arm250},
@samp{arm10e}, @samp{arm1020e}, @samp{arm1022e},
@samp{arm1136j-s}, @samp{arm1136jf-s}, @samp{mpcore}, @samp{mpcorenovfp},
@samp{arm1156t2-s}, @samp{arm1176jz-s}, @samp{arm1176jzf-s},
-@samp{cortex-a8}, @samp{cortex-r4}, @samp{cortex-r4f}, @samp{cortex-m3},
+@samp{cortex-a8}, @samp{cortex-a9},
+@samp{cortex-r4}, @samp{cortex-r4f}, @samp{cortex-m3},
@samp{cortex-m1},
@samp{xscale}, @samp{iwmmxt}, @samp{ep9312}.
@@ -8909,7 +8913,8 @@ name to determine what kind of instructions it can emit when generating
assembly code. This option can be used in conjunction with or instead
of the @option{-mcpu=} option. Permissible names are: @samp{armv2},
@samp{armv2a}, @samp{armv3}, @samp{armv3m}, @samp{armv4}, @samp{armv4t},
-@samp{armv5}, @samp{armv5t}, @samp{armv5te}, @samp{armv6}, @samp{armv6j},
+@samp{armv5}, @samp{armv5t}, @samp{armv5e}, @samp{armv5te},
+@samp{armv6}, @samp{armv6j},
@samp{armv6t2}, @samp{armv6z}, @samp{armv6zk}, @samp{armv6-m},
@samp{armv7}, @samp{armv7-a}, @samp{armv7-r}, @samp{armv7-m},
@samp{iwmmxt}, @samp{ep9312}.
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index b3d179910cc..d4eae5e593c 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,7 @@
+2009-01-14 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ * ChangeLog-2007: Clean out svn merge droppings.
+
2009-01-10 Paul Thomas <pault@gcc.gnu.org>
PR fortran/38763
diff --git a/gcc/fortran/ChangeLog-2007 b/gcc/fortran/ChangeLog-2007
index 9c34c79ca02..4597cb58fd3 100644
--- a/gcc/fortran/ChangeLog-2007
+++ b/gcc/fortran/ChangeLog-2007
@@ -87,7 +87,6 @@
* module.c (read_module): Check sym->module is there before
using it in a string comparison.
->>>>>>> .r131138
2007-12-20 Tobias Burnus <burnus@net-b.de>
PR fortran/34482
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 8e1938bd58a..e85d25de708 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1,6 +1,6 @@
/* Compiler driver program that can handle many languages.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GCC.
@@ -3382,6 +3382,9 @@ process_command (int argc, const char **argv)
char **new_argv;
char *new_argv0;
int baselen;
+ int status = 0;
+ int err = 0;
+ const char *errmsg;
while (argc > 1 && argv[1][0] == '-'
&& (argv[1][1] == 'V'
@@ -3424,8 +3427,18 @@ process_command (int argc, const char **argv)
new_argv = XDUPVEC (char *, argv, argc + 1);
new_argv[0] = new_argv0;
- execvp (new_argv0, new_argv);
- fatal ("couldn't run '%s': %s", new_argv0, xstrerror (errno));
+ errmsg = pex_one (PEX_SEARCH, new_argv0, new_argv, progname, NULL,
+ NULL, &status, &err);
+
+ if (errmsg)
+ {
+ if (err == 0)
+ fatal ("couldn't run '%s': %s", new_argv0, errmsg);
+ else
+ fatal ("couldn't run '%s': %s: %s", new_argv0, errmsg,
+ xstrerror (err));
+ }
+ exit (status);
}
/* Set up the default search paths. If there is no GCC_EXEC_PREFIX,
diff --git a/gcc/graphite.c b/gcc/graphite.c
index 27cadf3340d..116349b7202 100644
--- a/gcc/graphite.c
+++ b/gcc/graphite.c
@@ -61,14 +61,6 @@ along with GCC; see the file COPYING3. If not see
static VEC (scop_p, heap) *current_scops;
-/* Print GMP value V on stderr. */
-
-void
-debug_value (Value v)
-{
- value_print (stderr, "%4s\n", v);
-}
-
/* Converts a GMP constant V to a tree and returns it. */
static tree
@@ -4090,31 +4082,123 @@ is_iv (tree name)
}
static void expand_scalar_variables_stmt (gimple, basic_block, scop_p,
- loop_p, htab_t);
+ htab_t);
+static tree
+expand_scalar_variables_expr (tree, tree, enum tree_code, tree, basic_block,
+ scop_p, htab_t, gimple_stmt_iterator *);
+
+/* Copies at GSI all the scalar computations on which the ssa_name OP0
+ depends on in the SCOP: these are all the scalar variables used in
+ the definition of OP0, that are defined outside BB and still in the
+ SCOP, i.e. not a parameter of the SCOP. The expression that is
+ returned contains only induction variables from the generated code:
+ MAP contains the induction variables renaming mapping, and is used
+ to translate the names of induction variables. */
+
+static tree
+expand_scalar_variables_ssa_name (tree op0, basic_block bb,
+ scop_p scop, htab_t map,
+ gimple_stmt_iterator *gsi)
+{
+ tree var0, var1, type;
+ gimple def_stmt;
+ enum tree_code subcode;
+
+ if (is_parameter (scop, op0)
+ || is_iv (op0))
+ return get_new_name_from_old_name (map, op0);
+
+ def_stmt = SSA_NAME_DEF_STMT (op0);
+
+ if (gimple_bb (def_stmt) == bb)
+ {
+ /* If the defining statement is in the basic block already
+ we do not need to create a new expression for it, we
+ only need to ensure its operands are expanded. */
+ expand_scalar_variables_stmt (def_stmt, bb, scop, map);
+ return get_new_name_from_old_name (map, op0);
+ }
+ else
+ {
+ if (gimple_code (def_stmt) != GIMPLE_ASSIGN
+ || !bb_in_scop_p (gimple_bb (def_stmt), scop))
+ return get_new_name_from_old_name (map, op0);
-/* Constructs a tree which only contains old_ivs and parameters. Any
- other variables that are defined outside BB will be eliminated by
- using their definitions in the constructed tree. OLD_LOOP_FATHER
- is the original loop that contained BB. */
+ var0 = gimple_assign_rhs1 (def_stmt);
+ subcode = gimple_assign_rhs_code (def_stmt);
+ var1 = gimple_assign_rhs2 (def_stmt);
+ type = gimple_expr_type (def_stmt);
+
+ return expand_scalar_variables_expr (type, var0, subcode, var1, bb, scop,
+ map, gsi);
+ }
+}
+
+/* Copies at GSI all the scalar computations on which the expression
+ OP0 CODE OP1 depends on in the SCOP: these are all the scalar
+ variables used in OP0 and OP1, defined outside BB and still defined
+ in the SCOP, i.e. not a parameter of the SCOP. The expression that
+ is returned contains only induction variables from the generated
+ code: MAP contains the induction variables renaming mapping, and is
+ used to translate the names of induction variables. */
static tree
expand_scalar_variables_expr (tree type, tree op0, enum tree_code code,
tree op1, basic_block bb, scop_p scop,
- loop_p old_loop_father, htab_t map)
+ htab_t map, gimple_stmt_iterator *gsi)
{
- if ((TREE_CODE_CLASS (code) == tcc_constant
- && code == INTEGER_CST)
- || TREE_CODE_CLASS (code) == tcc_reference)
+ if (TREE_CODE_CLASS (code) == tcc_constant
+ || TREE_CODE_CLASS (code) == tcc_declaration)
return op0;
+ /* For data references we have to duplicate also its memory
+ indexing. */
+ if (TREE_CODE_CLASS (code) == tcc_reference)
+ {
+ switch (code)
+ {
+ case INDIRECT_REF:
+ {
+ tree old_name = TREE_OPERAND (op0, 0);
+ tree expr = expand_scalar_variables_ssa_name
+ (old_name, bb, scop, map, gsi);
+ tree new_name = force_gimple_operand_gsi (gsi, expr, true, NULL,
+ true, GSI_SAME_STMT);
+
+ set_symbol_mem_tag (SSA_NAME_VAR (new_name),
+ symbol_mem_tag (SSA_NAME_VAR (old_name)));
+ return fold_build1 (code, type, new_name);
+ }
+
+ case ARRAY_REF:
+ {
+ tree op00 = TREE_OPERAND (op0, 0);
+ tree op01 = TREE_OPERAND (op0, 1);
+ tree op02 = TREE_OPERAND (op0, 2);
+ tree op03 = TREE_OPERAND (op0, 3);
+ tree base = expand_scalar_variables_expr
+ (TREE_TYPE (op00), op00, TREE_CODE (op00), NULL, bb, scop,
+ map, gsi);
+ tree subscript = expand_scalar_variables_expr
+ (TREE_TYPE (op01), op01, TREE_CODE (op01), NULL, bb, scop,
+ map, gsi);
+
+ return build4 (ARRAY_REF, type, base, subscript, op02, op03);
+ }
+
+ default:
+ /* The above cases should catch everything. */
+ gcc_unreachable ();
+ }
+ }
+
if (TREE_CODE_CLASS (code) == tcc_unary)
{
tree op0_type = TREE_TYPE (op0);
enum tree_code op0_code = TREE_CODE (op0);
- tree op0_expr =
- expand_scalar_variables_expr (op0_type, op0, op0_code,
- NULL, bb, scop, old_loop_father, map);
-
+ tree op0_expr = expand_scalar_variables_expr (op0_type, op0, op0_code,
+ NULL, bb, scop, map, gsi);
+
return fold_build1 (code, type, op0_expr);
}
@@ -4122,68 +4206,38 @@ expand_scalar_variables_expr (tree type, tree op0, enum tree_code code,
{
tree op0_type = TREE_TYPE (op0);
enum tree_code op0_code = TREE_CODE (op0);
- tree op0_expr =
- expand_scalar_variables_expr (op0_type, op0, op0_code,
- NULL, bb, scop, old_loop_father, map);
+ tree op0_expr = expand_scalar_variables_expr (op0_type, op0, op0_code,
+ NULL, bb, scop, map, gsi);
tree op1_type = TREE_TYPE (op1);
enum tree_code op1_code = TREE_CODE (op1);
- tree op1_expr =
- expand_scalar_variables_expr (op1_type, op1, op1_code,
- NULL, bb, scop, old_loop_father, map);
+ tree op1_expr = expand_scalar_variables_expr (op1_type, op1, op1_code,
+ NULL, bb, scop, map, gsi);
return fold_build2 (code, type, op0_expr, op1_expr);
}
if (code == SSA_NAME)
- {
- tree var0, var1;
- gimple def_stmt;
- enum tree_code subcode;
-
- if (is_parameter (scop, op0)
- || is_iv (op0))
- return get_new_name_from_old_name (map, op0);
-
- def_stmt = SSA_NAME_DEF_STMT (op0);
-
- if (gimple_bb (def_stmt) == bb)
- {
- /* If the defining statement is in the basic block already
- we do not need to create a new expression for it, we
- only need to ensure its operands are expanded. */
- expand_scalar_variables_stmt (def_stmt, bb, scop,
- old_loop_father, map);
- return get_new_name_from_old_name (map, op0);
- }
- else
- {
- if (gimple_code (def_stmt) != GIMPLE_ASSIGN
- || !bb_in_scop_p (gimple_bb (def_stmt), scop))
- return get_new_name_from_old_name (map, op0);
-
- var0 = gimple_assign_rhs1 (def_stmt);
- subcode = gimple_assign_rhs_code (def_stmt);
- var1 = gimple_assign_rhs2 (def_stmt);
-
- return expand_scalar_variables_expr (type, var0, subcode, var1,
- bb, scop, old_loop_father, map);
- }
- }
+ return expand_scalar_variables_ssa_name (op0, bb, scop, map, gsi);
gcc_unreachable ();
return NULL;
}
-/* Replicates any uses of non-parameters and non-old-ivs variablesthat
- are defind outside BB with code that is inserted in BB.
- OLD_LOOP_FATHER is the original loop that contained STMT. */
+/* Copies at the beginning of BB all the scalar computations on which
+ STMT depends on in the SCOP: these are all the scalar variables used
+ in STMT, defined outside BB and still defined in the SCOP, i.e. not a
+ parameter of the SCOP. The expression that is returned contains
+ only induction variables from the generated code: MAP contains the
+ induction variables renaming mapping, and is used to translate the
+ names of induction variables. */
static void
expand_scalar_variables_stmt (gimple stmt, basic_block bb, scop_p scop,
- loop_p old_loop_father, htab_t map)
+ htab_t map)
{
ssa_op_iter iter;
use_operand_p use_p;
+ gimple_stmt_iterator gsi = gsi_after_labels (bb);
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
{
@@ -4191,10 +4245,9 @@ expand_scalar_variables_stmt (gimple stmt, basic_block bb, scop_p scop,
tree type = TREE_TYPE (use);
enum tree_code code = TREE_CODE (use);
tree use_expr = expand_scalar_variables_expr (type, use, code, NULL, bb,
- scop, old_loop_father, map);
+ scop, map, &gsi);
if (use_expr != use)
{
- gimple_stmt_iterator gsi = gsi_after_labels (bb);
tree new_use =
force_gimple_operand_gsi (&gsi, use_expr, true, NULL,
true, GSI_NEW_STMT);
@@ -4205,21 +4258,23 @@ expand_scalar_variables_stmt (gimple stmt, basic_block bb, scop_p scop,
update_stmt (stmt);
}
-/* Copies the definitions outside of BB of variables that are not
- induction variables nor parameters. BB must only contain
- "external" references to these types of variables. OLD_LOOP_FATHER
- is the original loop that contained BB. */
+/* Copies at the beginning of BB all the scalar computations on which
+ BB depends on in the SCOP: these are all the scalar variables used
+ in BB, defined outside BB and still defined in the SCOP, i.e. not a
+ parameter of the SCOP. The expression that is returned contains
+ only induction variables from the generated code: MAP contains the
+ induction variables renaming mapping, and is used to translate the
+ names of induction variables. */
static void
-expand_scalar_variables (basic_block bb, scop_p scop,
- loop_p old_loop_father, htab_t map)
+expand_scalar_variables (basic_block bb, scop_p scop, htab_t map)
{
gimple_stmt_iterator gsi;
for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
{
gimple stmt = gsi_stmt (gsi);
- expand_scalar_variables_stmt (stmt, bb, scop, old_loop_father, map);
+ expand_scalar_variables_stmt (stmt, bb, scop, map);
gsi_next (&gsi);
}
}
@@ -4396,7 +4451,6 @@ register_scop_liveout_renames (scop_p scop, htab_t rename_map)
static edge
copy_bb_and_scalar_dependences (basic_block bb, scop_p scop,
- loop_p context_loop,
edge next_e, htab_t map)
{
basic_block new_bb = split_edge (next_e);
@@ -4406,7 +4460,7 @@ copy_bb_and_scalar_dependences (basic_block bb, scop_p scop,
remove_condition (new_bb);
rename_variables (new_bb, map);
remove_phi_nodes (new_bb);
- expand_scalar_variables (new_bb, scop, context_loop, map);
+ expand_scalar_variables (new_bb, scop, map);
register_scop_liveout_renames (scop, map);
return next_e;
@@ -4578,7 +4632,7 @@ translate_clast (scop_p scop, struct loop *context_loop,
loop_iv_stack_patch_for_consts (ivstack, (struct clast_user_stmt *) stmt);
build_iv_mapping (ivstack, map, gbb, scop);
next_e = copy_bb_and_scalar_dependences (GBB_BB (gbb), scop,
- context_loop, next_e, map);
+ next_e, map);
htab_delete (map);
loop_iv_stack_remove_constants (ivstack);
update_ssa (TODO_update_ssa);
@@ -5118,6 +5172,82 @@ scop_insert_phis_for_liveouts (sese region, basic_block bb,
update_ssa (TODO_update_ssa);
}
+/* Get the definition of NAME before the SCOP. Keep track of the
+ basic blocks that have been VISITED in a bitmap. */
+
+static tree
+get_vdef_before_scop (scop_p scop, tree name, sbitmap visited)
+{
+ unsigned i;
+ gimple def_stmt = SSA_NAME_DEF_STMT (name);
+ basic_block def_bb = gimple_bb (def_stmt);
+
+ if (!bb_in_scop_p (def_bb, scop))
+ return name;
+
+ if (TEST_BIT (visited, def_bb->index))
+ return NULL_TREE;
+
+ SET_BIT (visited, def_bb->index);
+
+ switch (gimple_code (def_stmt))
+ {
+ case GIMPLE_PHI:
+ for (i = 0; i < gimple_phi_num_args (def_stmt); i++)
+ {
+ tree arg = gimple_phi_arg_def (def_stmt, i);
+ tree res = get_vdef_before_scop (scop, arg, visited);
+ if (res)
+ return res;
+ }
+ return NULL_TREE;
+
+ default:
+ return NULL_TREE;
+ }
+}
+
+/* Adjust a virtual phi node PHI that is placed at the end of the
+ generated code for SCOP:
+
+ | if (1)
+ | generated code from REGION;
+ | else
+ | REGION;
+
+ The FALSE_E edge comes from the original code, TRUE_E edge comes
+ from the code generated for the SCOP. */
+
+static void
+scop_adjust_vphi (scop_p scop, gimple phi, edge true_e)
+{
+ unsigned i;
+
+ gcc_assert (gimple_phi_num_args (phi) == 2);
+
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
+ if (gimple_phi_arg_edge (phi, i) == true_e)
+ {
+ tree true_arg, false_arg, before_scop_arg;
+ sbitmap visited;
+
+ true_arg = gimple_phi_arg_def (phi, i);
+ if (!SSA_NAME_IS_DEFAULT_DEF (true_arg))
+ return;
+
+ false_arg = gimple_phi_arg_def (phi, i == 0 ? 1 : 0);
+ if (SSA_NAME_IS_DEFAULT_DEF (false_arg))
+ return;
+
+ visited = sbitmap_alloc (last_basic_block);
+ sbitmap_zero (visited);
+ before_scop_arg = get_vdef_before_scop (scop, false_arg, visited);
+ gcc_assert (before_scop_arg != NULL_TREE);
+ SET_PHI_ARG_DEF (phi, i, before_scop_arg);
+ sbitmap_free (visited);
+ }
+}
+
/* Adjusts the phi nodes in the block BB for variables defined in
SCOP_REGION and used outside the SCOP_REGION. The code generation
moves SCOP_REGION in the else clause of an "if (1)" and generates
@@ -5144,7 +5274,10 @@ scop_adjust_phis_for_liveouts (scop_p scop, basic_block bb, edge false_e,
gimple phi = gsi_stmt (si);
if (!is_gimple_reg (PHI_RESULT (phi)))
- continue;
+ {
+ scop_adjust_vphi (scop, phi, true_e);
+ continue;
+ }
for (i = 0; i < gimple_phi_num_args (phi); i++)
if (gimple_phi_arg_edge (phi, i) == false_e)
@@ -5326,9 +5459,6 @@ gloog (scop_p scop, struct clast_stmt *stmt)
recompute_all_dominators ();
graphite_verify ();
- cleanup_tree_cfg ();
- recompute_all_dominators ();
- graphite_verify ();
}
/* Returns the number of data references in SCOP. */
@@ -6022,6 +6152,7 @@ graphite_transform_loops (void)
}
/* Cleanup. */
+ cleanup_tree_cfg ();
free_scops (current_scops);
cloog_finalize ();
free_original_copy_tables ();
diff --git a/gcc/graphite.h b/gcc/graphite.h
index a1801966ed1..76f26c8728a 100644
--- a/gcc/graphite.h
+++ b/gcc/graphite.h
@@ -381,7 +381,6 @@ extern void debug_rename_map (htab_t);
extern void debug_ivtype_map (htab_t);
extern void debug_loop_vec (graphite_bb_p);
extern void debug_oldivs (scop_p);
-extern void debug_value (Value);
/* Describes the type of an iv stack entry. */
typedef enum {
diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c
index 244d3bc9b3e..cce2abfd6f6 100644
--- a/gcc/ira-conflicts.c
+++ b/gcc/ira-conflicts.c
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "df.h"
#include "sparseset.h"
#include "ira-int.h"
+#include "addresses.h"
/* This file contains code responsible for allocno conflict creation,
allocno copy creation and allocno info accumulation on upper level
@@ -788,12 +789,12 @@ ira_build_conflicts (void)
ira_free (conflicts);
}
}
- if (! CLASS_LIKELY_SPILLED_P (BASE_REG_CLASS))
+ if (! CLASS_LIKELY_SPILLED_P (base_reg_class (VOIDmode, ADDRESS, SCRATCH)))
CLEAR_HARD_REG_SET (temp_hard_reg_set);
else
{
COPY_HARD_REG_SET (temp_hard_reg_set,
- reg_class_contents[BASE_REG_CLASS]);
+ reg_class_contents[base_reg_class (VOIDmode, ADDRESS, SCRATCH)]);
AND_COMPL_HARD_REG_SET (temp_hard_reg_set, ira_no_alloc_regs);
AND_HARD_REG_SET (temp_hard_reg_set, call_used_reg_set);
}
diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c
index c7868f39a54..0d1e402d82b 100644
--- a/gcc/ira-lives.c
+++ b/gcc/ira-lives.c
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "tm_p.h"
#include "target.h"
#include "flags.h"
+#include "except.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "insn-config.h"
@@ -985,6 +986,13 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
SET_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a));
SET_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a));
}
+ if (can_throw_internal (insn))
+ {
+ IOR_HARD_REG_SET (ALLOCNO_TOTAL_CONFLICT_HARD_REGS (a),
+ call_used_reg_set);
+ IOR_HARD_REG_SET (ALLOCNO_CONFLICT_HARD_REGS (a),
+ call_used_reg_set);
+ }
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a34e95f44f9..237ce656c31 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,140 @@
+2009-01-15 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/38636
+ * g++.dg/parse/crash50.C: New test.
+
+2009-01-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/38245
+ * gcc.dg/pr38245-3.c: New test.
+ * gcc.dg/pr38245-3.h: New file.
+ * gcc.dg/pr38245-4.c: New file.
+ * gcc.dg/pr38364.c: New test.
+
+2009-01-14 Adam Nemet <anemet@caviumnetworks.com>
+
+ * gcc.target/mips/mips.exp (mips_option_tests(-mips16)): Make the
+ sequence PC-relative.
+
+2009-01-14 Mark Mitchell <mark@codesourcery.com>
+
+ * gcc.target/arm/long-calls-1.c: Tolerate the lack of sibling
+ calls and/or PLT markers.
+ * gcc.target/arm/long-calls-2.c: Tolerate the lack of sibling
+ calls and/or PLT markers.
+ * gcc.target/arm/long-calls-3.c: Tolerate the lack of sibling
+ calls and/or PLT markers.
+ * gcc.target/arm/long-calls-4.c: Tolerate the lack of sibling
+ calls and/or PLT markers.
+
+2009-01-14 Daniel Jacobowitz <dan@codesourcery.com>
+ Nathan Froyd <froydnj@codesourcery.com>
+ Joseph Myers <joseph@codesourcery.com>
+
+ * lib/target-supports.exp (check_effective_target_powerpc_spe_nocache):
+ New function.
+ * gcc.target/powerpc/20030218-1.c: Skip if not powerpc_spe_nocache
+ and use consistent CFLAGS.
+ * gcc.target/powerpc/20030505.c: Likewise.
+ * gcc.target/powerpc/20081204-1.c: Likewise.
+ * gcc.target/powerpc/ppc-spe.c: Likewise.
+ * gcc.target/powerpc/spe1.c: Likewise.
+ * g++.dg/ext/spe1.C: Likewise.
+ * g++.dg/other/opaque-1.C: Likewise.
+ * g++.dg/other/opaque-2.C: Likewise.
+ * g++.dg/other/opaque-3.C: Likewise.
+
+2009-01-14 Mark Mitchell <mark@codesourcery.com>
+
+ * gcc.dg/vect/vect-105.c: Prevent compiler from hoisting abort
+ out of loop.
+
+2009-01-14 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/38826
+ PR middle-end/38477
+ * gcc.dg/Wstrict-aliasing-bogus-pta-1.c: New testcase.
+
+2009-01-13 Sebastian Pop <sebastian.pop@amd.com>
+
+ * gcc.dg/graphite/pr38786.c: Fix commit problem.
+
+2009-01-14 Nick Clifton <nickc@redhat.com>
+
+ PR c++/37862
+ * g++.cp/parse/pr37862.C: New test.
+
+2009-01-14 Julian Brown <julian@codesourcery.com>
+
+ * gcc.target/arm/eabi1.c (__eabi_uread4, __eabi_uwrite4)
+ (__eabi_uread8, __eabi_uwrite8): Change spellings of declarations
+ to...
+ (__aeabi_uread4, __aeabi_uwrite4, __aeabi_uread8, __aeabi_uwrite8):
+ These.
+
+2009-01-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/38774
+ * gcc.dg/torture/pr38774.c: New test.
+
+ PR c++/38795
+ * g++.dg/cpp0x/pr38795.C: New test.
+
+2009-01-13 Daniel Jacobowitz <dan@codesourcery.com>
+ Nathan Froyd <froydnj@codesourcery.com>
+ Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.target/powerpc/altivec-consts.c: Run if vmx_hw, compile
+ otherwise. Do not check for AltiVec at runtime.
+ * gcc.target/powerpc/altivec-varargs-1.c: Likewise.
+ * gcc.target/powerpc/altivec-vec-merge.c: Likewise.
+ * gcc.target/powerpc/altivec-1.c: Likewise.
+ * gcc.target/powerpc/altivec-3.c: Likewise.
+ * gcc.target/powerpc/altivec-10.c: Likewise.
+ * gcc.target/powerpc/altivec-12.c: Likewise.
+ * gcc.target/powerpc/altivec-24.c: Likewise.
+ * gcc.target/powerpc/altivec-cell-2.c: Likewise.
+ * gcc.target/powerpc/altivec-cell-3.c: Likewise.
+ * gcc.target/powerpc/altivec-cell-4.c: Likewise.
+ * gcc.target/powerpc/pr35907.c: Likewise.
+ * gcc.target/powerpc/altivec-cell-8.c: Run if cell_hw, compile
+ otherwise. Do not check for Cell at runtime.
+ * gcc.target/powerpc/altivec_check.h: Delete.
+
+ * g++.dg/ext/altivec-2.C: Do not check for AltiVec at runtime.
+ * g++.dg/ext/altivec-3.C: Run if vmx_hw, compile otherwise. Do
+ not check for AltiVec at runtime.
+ * g++.dg/ext/altivec-cell-2.C: Likewise.
+ * g++.dg/ext/altivec-cell-3.C: Likewise.
+ * g++.dg/ext/altivec-cell-4.C: Likewise.
+ * g++.dg/eh/simd-2.C: Only use -maltivec if vmx_hw.
+ * g++.dg/eh/check-vect.h (sig_ill_handler): Remove AltiVec runtime
+ check.
+ * g++.dg/ext/altivec_check.h: Delete.
+
+2009-01-13 Nathan Froyd <froydnj@codesourcery.com>
+
+ * gcc.target/powerpc/altivec-macros.c: Require a powerpc_altivec_ok
+ effective target. Adjust line numbers accordingly.
+
+2009-01-13 Mark Mitchell <mark@codesourcery.com>
+
+ * gcc.target/i386/sse-10.c: Pass -mno-omit-leaf-frame-pointer.
+
+2009-01-13 Sebastian Pop <sebastian.pop@amd.com>
+
+ PR tree-optimization/38786
+ * gcc.dg/graphite/pr38786.c: New.
+
+2009-01-13 Uros Bizjak <ubizjak@gmail.com>
+
+ Revert:
+ 2009-01-05 Uros Bizjak <ubizjak@gmail.com>
+
+ * gcc.dg/compat/struct-layout-1_generate.c (dg-options): Add -mieee
+ for alpha*-*-* targets.
+ * g++.dg/compat/struct-layout-1_generate.c (dg-options): Ditto.
+
2009-01-12 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libfortran/38772
diff --git a/gcc/testsuite/ChangeLog-2008 b/gcc/testsuite/ChangeLog-2008
index e89a011549a..281c8a66527 100644
--- a/gcc/testsuite/ChangeLog-2008
+++ b/gcc/testsuite/ChangeLog-2008
@@ -3280,7 +3280,6 @@
PR tree-optimization/37508
* gcc.dg/tree-ssa/pr37508.c: New testcase.
->>>>>>> .r140590
2008-09-15 Aldy Hernandez <aldyh@redhat.com>
* g++.old-deja/g++.brendan/crash16.C: Function name is the correct
diff --git a/gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c b/gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c
index b314d7079b3..575ad61a01a 100644
--- a/gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c
+++ b/gcc/testsuite/g++.dg/compat/struct-layout-1_generate.c
@@ -48,8 +48,7 @@ const char *dg_options[] = {
"/* { dg-options \"%s-I%s -fno-common\" { target hppa*-*-hpux* powerpc*-*-darwin* *-*-mingw32* *-*-cygwin* } } */\n",
"/* { dg-options \"%s-I%s -mno-mmx -fno-common\" { target i?86-*-darwin* x86_64-*-darwin* } } */\n",
"/* { dg-options \"%s-I%s -mno-base-addresses\" { target mmix-*-* } } */\n",
-"/* { dg-options \"%s-I%s -mlongcalls -mtext-section-literals\" { target xtensa*-*-* } } */\n",
-"/* { dg-options \"%s-I%s -mieee\" { target alpha*-*-* } } */\n"
+"/* { dg-options \"%s-I%s -mlongcalls -mtext-section-literals\" { target xtensa*-*-* } } */\n"
#define NDG_OPTIONS (sizeof (dg_options) / sizeof (dg_options[0]))
};
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr38795.C b/gcc/testsuite/g++.dg/cpp0x/pr38795.C
new file mode 100644
index 00000000000..54fb361d3d4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr38795.C
@@ -0,0 +1,13 @@
+// PR c++/38795
+// { dg-do compile }
+// { dg-options "-std=gnu++0x" }
+
+template<typename... T> int foo(int i)
+{
+ return *reinterpret_cast<T*>(i); // { dg-error "not expanded with|T" }
+}
+
+void bar(int i)
+{
+ foo<int>(i);
+}
diff --git a/gcc/testsuite/g++.dg/eh/check-vect.h b/gcc/testsuite/g++.dg/eh/check-vect.h
index 4321be0a4a6..b46a8827598 100644
--- a/gcc/testsuite/g++.dg/eh/check-vect.h
+++ b/gcc/testsuite/g++.dg/eh/check-vect.h
@@ -13,10 +13,7 @@ sig_ill_handler (int sig)
void check_vect (void)
{
signal(SIGILL, sig_ill_handler);
-#if defined(__ppc__) || defined(__ppc64__) || defined(__powerpc__) || defined(powerpc)
- /* Altivec instruction, 'vor %v0,%v0,%v0'. */
- asm volatile (".long 0x10000484");
-#elif defined(__i386__) || defined(__x86_64__)
+#if defined(__i386__) || defined(__x86_64__)
/* SSE2 instruction: movsd %xmm0,%xmm0 */
asm volatile (".byte 0xf2,0x0f,0x10,0xc0");
#elif defined(__sparc__)
diff --git a/gcc/testsuite/g++.dg/eh/simd-2.C b/gcc/testsuite/g++.dg/eh/simd-2.C
index e2af86636ac..b4c8690e9de 100644
--- a/gcc/testsuite/g++.dg/eh/simd-2.C
+++ b/gcc/testsuite/g++.dg/eh/simd-2.C
@@ -3,9 +3,7 @@
// { dg-options "-O" }
// { dg-options "-O -w" { target { { i?86-*-* x86_64-*-* } && ilp32 } } }
// { dg-options "-O -w" { target powerpc*-*-* } }
-// { dg-options "-O -w -maltivec" { target { powerpc*-*-linux* && powerpc_altivec_ok } } }
-// { dg-options "-O -w -maltivec" { target { powerpc*-*-darwin* && powerpc_altivec_ok } } }
-// { dg-xfail-if "" { "powerpc-*-eabispe*" "powerpc-ibm-aix*" } { "*" } { "" } }
+// { dg-options "-O -w -maltivec" { target { powerpc*-*-* && vmx_hw } } }
// { dg-do run }
#include "check-vect.h"
diff --git a/gcc/testsuite/g++.dg/ext/altivec-2.C b/gcc/testsuite/g++.dg/ext/altivec-2.C
index 268ff998946..299693694f6 100644
--- a/gcc/testsuite/g++.dg/ext/altivec-2.C
+++ b/gcc/testsuite/g++.dg/ext/altivec-2.C
@@ -6,7 +6,6 @@
arguments. */
#include <altivec.h>
-#include "altivec_check.h"
int main (int argc, const char * argv[])
{
@@ -15,8 +14,6 @@ int main (int argc, const char * argv[])
vector float v;
const vector float cv = (vector float){1.0, 2.0, 3.0, 4.0};
- altivec_check ();
-
vec_dst(&cv, i, 0);
v = vec_ld(0, &cv);
v = vec_lde(0, &cf);
diff --git a/gcc/testsuite/g++.dg/ext/altivec-3.C b/gcc/testsuite/g++.dg/ext/altivec-3.C
index d42303d8140..15113205950 100644
--- a/gcc/testsuite/g++.dg/ext/altivec-3.C
+++ b/gcc/testsuite/g++.dg/ext/altivec-3.C
@@ -1,4 +1,5 @@
-/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-maltivec" } */
@@ -10,7 +11,6 @@
#include <stdlib.h>
#include <altivec.h>
-#include "altivec_check.h"
#define CHECK_INVARIANT(expr) \
if (!(expr)) { \
@@ -132,7 +132,6 @@ void main1(void)
int main(void)
{
- altivec_check();
main1();
return 0;
}
diff --git a/gcc/testsuite/g++.dg/ext/altivec-cell-2.C b/gcc/testsuite/g++.dg/ext/altivec-cell-2.C
index 969cc97aa8a..f0d3433cdd9 100644
--- a/gcc/testsuite/g++.dg/ext/altivec-cell-2.C
+++ b/gcc/testsuite/g++.dg/ext/altivec-cell-2.C
@@ -1,9 +1,9 @@
-/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-maltivec" } */
/* Test the vec_extract VMX intrinsics. */
#include <altivec.h>
-#include "altivec_check.h"
extern "C" void abort (void);
@@ -137,6 +137,5 @@ int main1(void)
int main(void)
{
- altivec_check(); /* Exits if AltiVec not supported */
return main1 ();
}
diff --git a/gcc/testsuite/g++.dg/ext/altivec-cell-3.C b/gcc/testsuite/g++.dg/ext/altivec-cell-3.C
index f7ebcae054e..bd7e774e3cd 100644
--- a/gcc/testsuite/g++.dg/ext/altivec-cell-3.C
+++ b/gcc/testsuite/g++.dg/ext/altivec-cell-3.C
@@ -1,9 +1,9 @@
-/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-maltivec" } */
/* Test the vec_splats and vec_promote VMX intrinsics. */
#include <altivec.h>
-#include "altivec_check.h"
extern "C" void abort (void);
@@ -33,6 +33,5 @@ int main1(int t)
int main(void)
{
- altivec_check(); /* Exits if AltiVec not supported */
return main1 (0);
}
diff --git a/gcc/testsuite/g++.dg/ext/altivec-cell-4.C b/gcc/testsuite/g++.dg/ext/altivec-cell-4.C
index 10ab162dad2..7d91adbb34e 100644
--- a/gcc/testsuite/g++.dg/ext/altivec-cell-4.C
+++ b/gcc/testsuite/g++.dg/ext/altivec-cell-4.C
@@ -1,10 +1,10 @@
-/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-maltivec" } */
/* Test the vec_splats and vec_promote VMX intrinsics. */
#include <altivec.h>
-#include "altivec_check.h"
extern "C" void abort (void);
@@ -38,6 +38,5 @@ int main1(int t)
int main(void)
{
- altivec_check(); /* Exits if AltiVec not supported */
return main1 (0);
}
diff --git a/gcc/testsuite/g++.dg/ext/altivec_check.h b/gcc/testsuite/g++.dg/ext/altivec_check.h
deleted file mode 100644
index 9e8b3f78ac2..00000000000
--- a/gcc/testsuite/g++.dg/ext/altivec_check.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* A runtime check for AltiVec capability. */
-/* Contributed by Ziemowit Laski <zlaski@apple.com> */
-
-#include <signal.h>
-extern
-#ifdef __cplusplus
-"C"
-#endif
-void exit(int);
-
-void
-sig_ill_handler (int sig)
-{
- exit (0);
-}
-
-void altivec_check(void) {
-
- /* Exit on systems without AltiVec. */
- signal (SIGILL, sig_ill_handler);
-#ifdef __MACH__
- asm volatile ("vor v0,v0,v0");
-#else
- asm volatile ("vor 0,0,0");
-#endif
- signal (SIGILL, SIG_DFL);
-}
diff --git a/gcc/testsuite/g++.dg/ext/spe1.C b/gcc/testsuite/g++.dg/ext/spe1.C
index fdd213964b4..8b1e630ecc0 100644
--- a/gcc/testsuite/g++.dg/ext/spe1.C
+++ b/gcc/testsuite/g++.dg/ext/spe1.C
@@ -1,5 +1,6 @@
-/* { dg-do compile { target powerpc-*-eabi* } } */
+/* { dg-do compile } */
/* { dg-options "-mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single -O0" } */
+/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */
typedef int v2si __attribute__ ((vector_size (8)));
diff --git a/gcc/testsuite/g++.dg/other/opaque-1.C b/gcc/testsuite/g++.dg/other/opaque-1.C
index fa79f6f2a1e..5cdaeafe31a 100644
--- a/gcc/testsuite/g++.dg/other/opaque-1.C
+++ b/gcc/testsuite/g++.dg/other/opaque-1.C
@@ -1,4 +1,6 @@
-/* { dg-do run { target { powerpc*-*-* && powerpc_spe } } } */
+/* { dg-do run } */
+/* { dg-options "-mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single" } */
+/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */
#define __vector __attribute__((vector_size(8)))
typedef float __vector __ev64_fs__;
diff --git a/gcc/testsuite/g++.dg/other/opaque-2.C b/gcc/testsuite/g++.dg/other/opaque-2.C
index 6b13ba2810d..3bb4af2c778 100644
--- a/gcc/testsuite/g++.dg/other/opaque-2.C
+++ b/gcc/testsuite/g++.dg/other/opaque-2.C
@@ -1,5 +1,6 @@
-/* { dg-do compile { target powerpc-*-eabi* powerpc*-*-linux*spe* } } */
+/* { dg-do compile } */
/* { dg-options "-mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single" } */
+/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */
#define __vector __attribute__((vector_size(8)))
typedef float __vector __ev64_fs__;
diff --git a/gcc/testsuite/g++.dg/other/opaque-3.C b/gcc/testsuite/g++.dg/other/opaque-3.C
index cf8119ffcac..5ece652c0cd 100644
--- a/gcc/testsuite/g++.dg/other/opaque-3.C
+++ b/gcc/testsuite/g++.dg/other/opaque-3.C
@@ -1,5 +1,6 @@
-/* { dg-do compile { target powerpc-*-eabi* powerpc*-*-linux*spe* } } */
+/* { dg-do compile } */
/* { dg-options "-mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single" } */
+/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */
__ev64_opaque__ o;
#define v __attribute__((vector_size(8)))
diff --git a/gcc/testsuite/g++.dg/parse/crash50.C b/gcc/testsuite/g++.dg/parse/crash50.C
new file mode 100644
index 00000000000..711048de160
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash50.C
@@ -0,0 +1,10 @@
+// Contributed by Dodji Seketeli <dodji@redhat.com>
+// Origin PR c++/38636
+// { dg-do compile }
+
+struct A; // { dg-error "forward declaration of 'struct A'" }
+
+A::A(
+
+struct B; // { dg-error "expected '\\)' before ';' token|invalid use of incomplete type 'struct A'" }
+
diff --git a/gcc/testsuite/g++.dg/parse/pr37862.C b/gcc/testsuite/g++.dg/parse/pr37862.C
new file mode 100644
index 00000000000..89b4b699475
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/pr37862.C
@@ -0,0 +1,25 @@
+// { dg-do run }
+#include <stdlib.h>
+
+class A {
+public:
+ virtual void get (void) { }
+};
+
+class B : public A {
+public:
+ void get (void) { abort (); }
+};
+
+class C : public B { };
+
+int main (void)
+{
+ C c;
+ C * p = &c;
+
+ p->A::get ();
+ (p->A::get) (); // The C++ parser used to resolve this to B::get()
+
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr38811.C b/gcc/testsuite/g++.dg/torture/pr38811.C
new file mode 100644
index 00000000000..e9b304da6e5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr38811.C
@@ -0,0 +1,73 @@
+/* { dg-do compile } */
+
+typedef unsigned long ULONG;
+void iwos_ErrorMessage(long error, const char * const file_name,
+ ULONG line_num, const char * const message);
+class AbcA2d {
+public:
+ double x;
+ double y;
+ ~AbcA2d() { }
+};
+enum AbcZyParamType { ABC_SP_1 };
+class AbcExtent2d {
+ AbcA2d m_vMin;
+ AbcA2d m_vMax;
+public:
+ AbcExtent2d(const AbcA2d & rMin, const AbcA2d & rMax);
+ AbcA2d ClampPoint2d(const AbcA2d & rPoint) const;
+ AbcA2d GetMax() const { return m_vMax; }
+ AbcA2d GetMin() const { }
+ AbcA2d Evaluate(double dNormalizedX, double dNormalizedY) const;
+};
+inline AbcExtent2d::AbcExtent2d(const AbcA2d & rMin, const AbcA2d & rMax)
+{
+ if (rMin.x > rMax.x || rMin.y > rMax.y)
+ {
+ long sErr = (1007);
+ if (sErr != 1000)
+ iwos_ErrorMessage(sErr,(const char * const)__null,
+ 0,(const char * const)__null);
+ }
+ else
+ {
+ m_vMin = rMin;
+ m_vMax = rMax;
+ }
+}
+inline AbcA2d AbcExtent2d::ClampPoint2d(const AbcA2d & rPoint) const
+{
+ AbcA2d sRet = rPoint;
+ if (rPoint.x < m_vMin.x)
+ sRet.x = m_vMin.x;
+ return sRet;
+}
+inline AbcA2d AbcExtent2d::Evaluate(double dNormalizedX, double dNormalizedY)
+const
+{
+ AbcA2d sRet;
+ sRet.x = m_vMin.x + dNormalizedX * (m_vMax.x - m_vMin.x);
+ sRet.y = m_vMin.y + dNormalizedY * (m_vMax.y - m_vMin.y);
+ return ClampPoint2d(sRet);
+}
+class AbcAbcdTracer {
+ AbcExtent2d m_vUVDomain;
+ virtual long TestIsoAbcde(AbcZyParamType eZyParam, double dParam,
+ int & rbZyxIsSolution);
+ virtual int DoesPointLieOnAbcde(AbcA2d & rUV, int bRefinePoint) const;
+};
+long AbcAbcdTracer::TestIsoAbcde(AbcZyParamType eZyParam, double dParam,
+ int & rbZyxIsSolution)
+{
+ AbcA2d sUV1(m_vUVDomain.GetMin());
+ AbcA2d sUV2(m_vUVDomain.GetMax());
+ AbcExtent2d sUVIso(sUV1,sUV2);
+ for (ULONG i=0; i<10; i++)
+ {
+ double dT = i / (10 -1.0);
+ AbcA2d sUV = sUVIso.Evaluate(dT,dT);
+ if (!DoesPointLieOnAbcde(sUV,0))
+ ;
+ }
+}
+
diff --git a/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-pta-1.c b/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-pta-1.c
new file mode 100644
index 00000000000..a48827474d7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstrict-aliasing-bogus-pta-1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall" } */
+
+struct S { int *p; int *q; };
+
+void foo (struct S *);
+
+int bar (int b)
+{
+ struct S s;
+ int *p;
+ float f;
+ foo (&s);
+ if (b)
+ p = s.q;
+ else
+ p = (int *)&f;
+ return *p;
+}
diff --git a/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c b/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c
index 26e65723323..a162dee42a4 100644
--- a/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c
+++ b/gcc/testsuite/gcc.dg/compat/struct-layout-1_generate.c
@@ -48,8 +48,7 @@ const char *dg_options[] = {
"/* { dg-options \"%s-I%s -fno-common\" { target hppa*-*-hpux* powerpc*-*-darwin* *-*-mingw32* *-*-cygwin* } } */\n",
"/* { dg-options \"%s-I%s -mno-mmx -fno-common\" { target i?86-*-darwin* x86_64-*-darwin* } } */\n",
"/* { dg-options \"%s-I%s -mno-base-addresses\" { target mmix-*-* } } */\n",
-"/* { dg-options \"%s-I%s -mlongcalls -mtext-section-literals\" { target xtensa*-*-* } } */\n",
-"/* { dg-options \"%s-I%s -mieee\" { target alpha*-*-* } } */\n"
+"/* { dg-options \"%s-I%s -mlongcalls -mtext-section-literals\" { target xtensa*-*-* } } */\n"
#define NDG_OPTIONS (sizeof (dg_options) / sizeof (dg_options[0]))
};
diff --git a/gcc/testsuite/gcc.dg/graphite/pr38786.c b/gcc/testsuite/gcc.dg/graphite/pr38786.c
new file mode 100644
index 00000000000..47df44789f8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/graphite/pr38786.c
@@ -0,0 +1,20 @@
+/* { dg-options "-O2 -fgraphite-identity" } */
+
+typedef struct
+{
+ int ****cofAC;
+} ImageParameters;
+typedef struct
+{
+ int ****cofAC;
+} RD_DATA;
+extern RD_DATA *rdopt;
+extern ImageParameters *img;
+dummy_slice_too_big (int bits_slice)
+{
+ int i, j, k, l;
+ for (j = 0; j < 4; j++)
+ for (k = 0; k < 2; k++)
+ for (l = 0; l < 65; l++)
+ img->cofAC[i][j][k][l] = rdopt->cofAC[i][j][k][l];
+}
diff --git a/gcc/testsuite/gcc.dg/pr38245-3.c b/gcc/testsuite/gcc.dg/pr38245-3.c
new file mode 100644
index 00000000000..6ef8372a14f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr38245-3.c
@@ -0,0 +1,112 @@
+/* PR rtl-optimization/38245 */
+/* { dg-do run } */
+/* { dg-additional-sources "pr38245-4.c" } */
+/* { dg-options "-O2" } */
+
+#include "pr38245-3.h"
+
+extern void abort (void);
+
+struct A { int i, j; union { short s[4]; long long l; }; char pad[512]; } a;
+int globv = 6;
+
+void __attribute__((noinline))
+f1 (void)
+{
+ a.s[2] = b1 (6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21);
+ a.l = 6;
+}
+
+void __attribute__((noinline))
+f2 (void)
+{
+ a.s[2] = b2 (6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21);
+ a.l = 6;
+}
+
+void __attribute__((noinline))
+f3 (void)
+{
+ struct B b = { 30, 31, { 32, 33 } };
+ a.s[2] = b3 (6, 7, 8, 9, 10, 11, 12, b, 14, b, 16, b, 18, 19, 20, 21,
+ 6, b, 8, b, 10, 11, 12, 13, 14, b, 16, b, 18, 19, 20, 21);
+ a.l = 6;
+}
+
+void __attribute__((noinline))
+f4 (void)
+{
+ struct B b = { 30, 31, { 32, 33 } };
+ a.s[2] = b4 (6, 7, 8, 9, 10, 11, 12, b, 14, b, 16, b, 18, 19, 20, 21,
+ 6, b, 8, b, 10, 11, 12, 13, 14, b, 16, b, 18, 19, 20, 21);
+ a.l = 6;
+}
+
+void __attribute__((noinline))
+f5 (void)
+{
+ a.s[2] = b5 (6.0, 7, 8, 9, 10, 11, 21.0, 22.0, 23.0);
+ a.l = 6;
+}
+
+void __attribute__((noinline))
+f6 (void)
+{
+ a.s[2] = b6 (6.0, 7, 8, 9, 10, 11, 21.0, 22.0, 23.0);
+ a.l = 6;
+}
+
+void __attribute__((noinline))
+f7 (void)
+{
+ a.s[2] = b7 (6, 7);
+ a.l = 6;
+}
+
+void __attribute__((noinline))
+f8 (void)
+{
+ a.s[2] = b8 (6, 7);
+ a.l = 6;
+}
+
+void __attribute__((noinline))
+f9 (void)
+{
+ a.s[2] = b9 (6, 7, 8, 9, 10, 11, 12);
+ a.l = 6;
+}
+
+void __attribute__((noinline))
+f10 (void)
+{
+ a.s[2] = b10 (6, 7, 8, 9, 10, 11, 12);
+ a.l = 6;
+}
+
+int
+main (void)
+{
+ char buf[256];
+ int i;
+ for (i = 0; i < (int) sizeof buf; i++)
+ buf[i] = i;
+ asm volatile ("" : : "r" (buf) : "memory");
+ f1 ();
+ f2 ();
+ f3 ();
+ f4 ();
+ f5 ();
+ f6 ();
+ f7 ();
+ f8 ();
+ f9 ();
+ f10 ();
+ asm volatile ("" : : "r" (buf) : "memory");
+ for (i = 0; i < (int) sizeof buf; i++)
+ if (buf[i] != (char) i)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr38245-3.h b/gcc/testsuite/gcc.dg/pr38245-3.h
new file mode 100644
index 00000000000..b1c2a0f67c2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr38245-3.h
@@ -0,0 +1,35 @@
+/* PR rtl-optimization/38245 */
+
+struct B { long a, b; char p[32]; };
+extern int globv;
+
+extern int b1 (long long, long, long, long, long, long, long, long,
+ long long, long, long, long, long, long, long, long,
+ long long, long, long, long, long, long, long, long,
+ long long, long, long, long, long, long, long, long)
+ __attribute__((pure, noinline));
+extern int b2 (long long, long, long, long, long, long, long, long,
+ long long, long, long, long, long, long, long, long,
+ long long, long, long, long, long, long, long, long,
+ long long, long, long, long, long, long, long, long)
+ __attribute__((const, noinline));
+extern int b3 (long long, long, long, long, long, long, long, struct B,
+ long long, struct B, long, struct B, long, long, long, long,
+ long long, struct B, long, struct B, long, long, long, long,
+ long long, struct B, long, struct B, long, long, long, long)
+ __attribute__((pure, noinline));
+extern int b4 (long long, long, long, long, long, long, long, struct B,
+ long long, struct B, long, struct B, long, long, long, long,
+ long long, struct B, long, struct B, long, long, long, long,
+ long long, struct B, long, struct B, long, long, long, long)
+ __attribute__((const, noinline));
+extern int b5 () __attribute__((pure, noinline));
+extern int b6 () __attribute__((const, noinline));
+extern int b7 (int, int)
+ __attribute__((pure, noinline));
+extern int b8 (int, int)
+ __attribute__((const, noinline));
+extern int b9 (int, int, int, int, int, int, int)
+ __attribute__((pure, noinline));
+extern int b10 (int, int, int, int, int, int, int)
+ __attribute__((const, noinline));
diff --git a/gcc/testsuite/gcc.dg/pr38245-4.c b/gcc/testsuite/gcc.dg/pr38245-4.c
new file mode 100644
index 00000000000..c9b3d2d8fb8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr38245-4.c
@@ -0,0 +1,107 @@
+/* PR rtl-optimization/38245 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+#include "pr38245-3.h"
+
+int
+b1 (long long a1, long a2, long a3, long a4,
+ long a5, long a6, long a7, long a8,
+ long long a9, long a10, long a11, long a12,
+ long a13, long a14, long a15, long a16,
+ long long a17, long a18, long a19, long a20,
+ long a21, long a22, long a23, long a24,
+ long long a25, long a26, long a27, long a28,
+ long a29, long a30, long a31, long a32)
+{
+ return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10
+ + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a20
+ + a21 + a22 + a23 + a24 + a25 + a26 + a27 + a28 + a29 + a30
+ + a31 + a32 + globv;
+}
+
+int
+b2 (long long a1, long a2, long a3, long a4,
+ long a5, long a6, long a7, long a8,
+ long long a9, long a10, long a11, long a12,
+ long a13, long a14, long a15, long a16,
+ long long a17, long a18, long a19, long a20,
+ long a21, long a22, long a23, long a24,
+ long long a25, long a26, long a27, long a28,
+ long a29, long a30, long a31, long a32)
+{
+ return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10
+ + a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a20
+ + a21 + a22 + a23 + a24 + a25 + a26 + a27 + a28 + a29 + a30
+ + a31 + a32;
+}
+
+int
+b3 (long long a1, long a2, long a3, long a4,
+ long a5, long a6, long a7, struct B a8,
+ long long a9, struct B a10, long a11, struct B a12,
+ long a13, long a14, long a15, long a16,
+ long long a17, struct B a18, long a19, struct B a20,
+ long a21, long a22, long a23, long a24,
+ long long a25, struct B a26, long a27, struct B a28,
+ long a29, long a30, long a31, long a32)
+{
+ return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8.a + a9 + a10.a
+ + a11 + a12.a + a13 + a14 + a15 + a16 + a17 + a18.a + a19 + a20.a
+ + a21 + a22 + a23 + a24 + a25 + a26.a + a27 + a28.a + a29 + a30
+ + a31 + a32 + globv;
+}
+
+int
+b4 (long long a1, long a2, long a3, long a4,
+ long a5, long a6, long a7, struct B a8,
+ long long a9, struct B a10, long a11, struct B a12,
+ long a13, long a14, long a15, long a16,
+ long long a17, struct B a18, long a19, struct B a20,
+ long a21, long a22, long a23, long a24,
+ long long a25, struct B a26, long a27, struct B a28,
+ long a29, long a30, long a31, long a32)
+{
+ return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8.a + a9 + a10.a
+ + a11 + a12.a + a13 + a14 + a15 + a16 + a17 + a18.a + a19 + a20.a
+ + a21 + a22 + a23 + a24 + a25 + a26.a + a27 + a28.a + a29 + a30
+ + a31 + a32;
+}
+
+int
+b5 (double a1, int a2, int a3, int a4, int a5, int a6, double a7,
+ double a8, double a9)
+{
+ return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + globv;
+}
+
+int
+b6 (double a1, int a2, int a3, int a4, int a5, int a6, double a7,
+ double a8, double a9)
+{
+ return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9;
+}
+
+int
+b7 (int a1, int a2)
+{
+ return a1 + a2 + globv;
+}
+
+int
+b8 (int a1, int a2)
+{
+ return a1 + a2;
+}
+
+int
+b9 (int a1, int a2, int a3, int a4, int a5, int a6, int a7)
+{
+ return a1 + a2 + a3 + a4 + a5 + a6 + a7 + globv;
+}
+
+int
+b10 (int a1, int a2, int a3, int a4, int a5, int a6, int a7)
+{
+ return a1 + a2 + a3 + a4 + a5 + a6 + a7;
+}
diff --git a/gcc/testsuite/gcc.dg/pr38364.c b/gcc/testsuite/gcc.dg/pr38364.c
new file mode 100644
index 00000000000..23f72de74ee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr38364.c
@@ -0,0 +1,79 @@
+/* PR middle-end/38364 */
+/* { dg-do run } */
+/* { dg-options "-O2 -ftrapv" } */
+
+extern void abort (void);
+
+static inline short
+f1 (short x, short y)
+{
+ if (x > 0)
+ {
+ if (y > 0)
+ {
+ if (x > __SHRT_MAX__ / y)
+ return x;
+ }
+ else if (y < (-__SHRT_MAX__ - 1) / x)
+ return x;
+ }
+ else
+ {
+ if (y > 0)
+ {
+ if (x < (-__SHRT_MAX__ - 1) / y)
+ return x;
+ }
+ else if (x != 0 && y < __SHRT_MAX__ / x)
+ return x;
+ }
+ return x * y;
+}
+
+static inline signed char
+f2 (signed char x, signed char y)
+{
+ if (((x ^ y) & (((x ^ ((x ^ y) & (1 << (__CHAR_BIT__ - 1)))) - y) ^ y)) < 0)
+ return x;
+ return x - y;
+}
+
+unsigned int v;
+
+int
+f3 (int x, unsigned int y)
+{
+ f1 (1, 1);
+ return 1;
+}
+
+int
+f4 (unsigned short x)
+{
+ v = x;
+ return 1;
+}
+
+int
+f5 (int x)
+{
+ if (f2 (x, 1))
+ f1 (1, f4 (1));
+ return x;
+}
+
+int
+f6 (unsigned int x)
+{
+ f4 (x < (1 != f5 (0)));
+ return x;
+}
+
+int
+main (void)
+{
+ f6 (1);
+ if (v != 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr38774.c b/gcc/testsuite/gcc.dg/torture/pr38774.c
new file mode 100644
index 00000000000..d6d7fcb0ff5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr38774.c
@@ -0,0 +1,16 @@
+/* PR rtl-optimization/38774 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+/* { dg-options "-march=i686" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */
+
+extern int bar (void);
+volatile int g;
+
+int
+foo (void)
+{
+ int a = 1 >= bar ();
+ if ((1 > 9223372036854775807LL - a && 1 - a ? : 1 + a) & 1)
+ return g;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-105.c b/gcc/testsuite/gcc.dg/vect/vect-105.c
index eb21b160cff..bbf42af897f 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-105.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-105.c
@@ -16,6 +16,8 @@ static int a[N][N] = {{1,2,3,11},{4,5,6,12},{7,8,9,13},{34,45,67,83}};
static int b[N][N] = {{17,28,15,23},{0,2,3,24},{4,31,82,25},{29,31,432,256}};
static int c[N][N] = {{1,2,3,11},{4,9,13,34},{45,67,83,13},{34,45,67,83}};
+volatile int y;
+
__attribute__ ((noinline))
int main1 (int x) {
int i,j;
@@ -28,7 +30,9 @@ int main1 (int x) {
{
p->a[i][j] = a[i][j];
p->b[i][j] = b[i][j];
- if (x == 135)
+ /* Because Y is volatile, the compiler cannot move this check out
+ of the loop. */
+ if (y)
abort (); /* to avoid vectorization */
}
}
diff --git a/gcc/testsuite/gcc.target/arm/eabi1.c b/gcc/testsuite/gcc.target/arm/eabi1.c
index 06af6710299..e88ba021fdc 100644
--- a/gcc/testsuite/gcc.target/arm/eabi1.c
+++ b/gcc/testsuite/gcc.target/arm/eabi1.c
@@ -75,10 +75,10 @@ extern int __aeabi_lcmp (long long, long long);
extern int __aeabi_ulcmp (unsigned long long, unsigned long long);
extern int __aeabi_idiv (int, int);
extern unsigned int __aeabi_uidiv (unsigned int, unsigned int);
-extern int __eabi_uread4 (void *);
-extern int __eabi_uwrite4 (int, void *);
-extern long long __eabi_uread8 (void *);
-extern long long __eabi_uwrite8 (long long, void *);
+extern int __aeabi_uread4 (void *);
+extern int __aeabi_uwrite4 (int, void *);
+extern long long __aeabi_uread8 (void *);
+extern long long __aeabi_uwrite8 (long long, void *);
#define eq(a, b, type, abs, epsilon, format) \
{ \
diff --git a/gcc/testsuite/gcc.target/arm/long-calls-1.c b/gcc/testsuite/gcc.target/arm/long-calls-1.c
index 7c2e7fe1c71..587f6d6f25b 100644
--- a/gcc/testsuite/gcc.target/arm/long-calls-1.c
+++ b/gcc/testsuite/gcc.target/arm/long-calls-1.c
@@ -38,8 +38,14 @@ DO_TESTS_CALL_ATTR (weak_, EXTERN_CALL, weak)
DO_TESTS_CALL_ATTR (static_, STATIC_CALL,)
-/* Calls to remote_* should honor the call type sttribute,
- with "short" being the default. */
+/* Calls to remote_* should honor the call type attribute,
+ with "short" being the default.
+
+ In the regular expressions below:
+
+ * We allow both "b" and "bl" in some cases to allow for the
+ possibility of sibling calls. As of this writing, GCC does not
+ use sibling calls in Thumb-2 mode. */
/* { dg-final { scan-assembler "\tbl\tremote_n1\n" } } */
/* { dg-final { scan-assembler "\tbl\tremote_n2\n" } } */
@@ -59,46 +65,46 @@ DO_TESTS_CALL_ATTR (static_, STATIC_CALL,)
should be short. */
/* { dg-final { scan-assembler "\tbl\tstrong_n1\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_n1\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_n1\n" } } */
/* { dg-final { scan-assembler "\tbl\tstrong_n2\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_n2\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_n2\n" } } */
/* { dg-final { scan-assembler "\tbl\tstrong_n3\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_n3\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_n3\n" } } */
/* { dg-final { scan-assembler "\tbl\tstrong_l1\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_l1\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_l1\n" } } */
/* { dg-final { scan-assembler-not "\tbl?\tstrong_l2\n" } } */
/* { dg-final { scan-assembler "\tbl\tstrong_l3\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_l3\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_l3\n" } } */
/* { dg-final { scan-assembler "\tbl\tstrong_s1\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_s1\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_s1\n" } } */
/* { dg-final { scan-assembler "\tbl\tstrong_s2\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_s2\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_s2\n" } } */
/* { dg-final { scan-assembler "\tbl\tstrong_s3\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_s3\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_s3\n" } } */
-/* Calls to weak_* should honor the call type sttribute,
+/* Calls to weak_* should honor the call type attribute,
with "short" being the default. */
/* { dg-final { scan-assembler "\tbl\tweak_n1\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_n1\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_n1\n" } } */
/* { dg-final { scan-assembler "\tbl\tweak_n2\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_n2\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_n2\n" } } */
/* { dg-final { scan-assembler "\tbl\tweak_n3\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_n3\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_n3\n" } } */
/* { dg-final { scan-assembler-not "\tbl?\tweak_l1\n" } } */
/* { dg-final { scan-assembler-not "\tbl?\tweak_l2\n" } } */
/* { dg-final { scan-assembler-not "\tbl?\tweak_l3\n" } } */
/* { dg-final { scan-assembler "\tbl\tweak_s1\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_s1\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_s1\n" } } */
/* { dg-final { scan-assembler "\tbl\tweak_s2\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_s2\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_s2\n" } } */
/* { dg-final { scan-assembler "\tbl\tweak_s3\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_s3\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_s3\n" } } */
/* Calls to static_*2 calls should honor the call type attribute,
@@ -106,21 +112,21 @@ DO_TESTS_CALL_ATTR (static_, STATIC_CALL,)
should be short. */
/* { dg-final { scan-assembler "\tbl\tstatic_n1\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_n1\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_n1\n" } } */
/* { dg-final { scan-assembler "\tbl\tstatic_n2\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_n2\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_n2\n" } } */
/* { dg-final { scan-assembler "\tbl\tstatic_n3\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_n3\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_n3\n" } } */
/* { dg-final { scan-assembler "\tbl\tstatic_l1\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_l1\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_l1\n" } } */
/* { dg-final { scan-assembler-not "\tbl?\tstatic_l2\n" } } */
/* { dg-final { scan-assembler "\tbl\tstatic_l3\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_l3\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_l3\n" } } */
/* { dg-final { scan-assembler "\tbl\tstatic_s1\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_s1\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_s1\n" } } */
/* { dg-final { scan-assembler "\tbl\tstatic_s2\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_s2\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_s2\n" } } */
/* { dg-final { scan-assembler "\tbl\tstatic_s3\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_s3\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_s3\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/long-calls-2.c b/gcc/testsuite/gcc.target/arm/long-calls-2.c
index c63f8abec3b..8ce2404c1f7 100644
--- a/gcc/testsuite/gcc.target/arm/long-calls-2.c
+++ b/gcc/testsuite/gcc.target/arm/long-calls-2.c
@@ -38,8 +38,14 @@ DO_TESTS_CALL_ATTR (weak_, EXTERN_CALL, weak)
DO_TESTS_CALL_ATTR (static_, STATIC_CALL,)
-/* Calls to remote_* should honor the call type sttribute,
- with "long" being the default. */
+/* Calls to remote_* should honor the call type attribute,
+ with "long" being the default.
+
+ In the regular expressions below:
+
+ * We allow both "b" and "bl" in some cases to allow for the
+ possibility of sibling calls. As of this writing, GCC does not
+ use sibling calls in Thumb-2 mode. */
/* { dg-final { scan-assembler-not "\tbl\tremote_n1\n" } } */
/* { dg-final { scan-assembler-not "\tbl\tremote_n2\n" } } */
@@ -59,26 +65,26 @@ DO_TESTS_CALL_ATTR (static_, STATIC_CALL,)
should be short. */
/* { dg-final { scan-assembler "\tbl\tstrong_n1\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_n1\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_n1\n" } } */
/* { dg-final { scan-assembler-not "\tbl\tstrong_n2\n" } } */
/* { dg-final { scan-assembler "\tbl\tstrong_n3\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_n3\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_n3\n" } } */
/* { dg-final { scan-assembler "\tbl\tstrong_l1\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_l1\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_l1\n" } } */
/* { dg-final { scan-assembler-not "\tbl?\tstrong_l2\n" } } */
/* { dg-final { scan-assembler "\tbl\tstrong_l3\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_l3\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_l3\n" } } */
/* { dg-final { scan-assembler "\tbl\tstrong_s1\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_s1\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_s1\n" } } */
/* { dg-final { scan-assembler "\tbl\tstrong_s2\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_s2\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_s2\n" } } */
/* { dg-final { scan-assembler "\tbl\tstrong_s3\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_s3\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_s3\n" } } */
-/* Calls to weak_* should honor the call type sttribute,
+/* Calls to weak_* should honor the call type attribute,
with "long" being the default. */
/* { dg-final { scan-assembler-not "\tbl?\tweak_n1\n" } } */
@@ -90,11 +96,11 @@ DO_TESTS_CALL_ATTR (static_, STATIC_CALL,)
/* { dg-final { scan-assembler-not "\tbl?\tweak_l3\n" } } */
/* { dg-final { scan-assembler "\tbl\tweak_s1\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_s1\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_s1\n" } } */
/* { dg-final { scan-assembler "\tbl\tweak_s2\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_s2\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_s2\n" } } */
/* { dg-final { scan-assembler "\tbl\tweak_s3\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_s3\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_s3\n" } } */
/* Calls to static_*2 calls should honor the call type attribute,
@@ -102,20 +108,20 @@ DO_TESTS_CALL_ATTR (static_, STATIC_CALL,)
should be short. */
/* { dg-final { scan-assembler "\tbl\tstatic_n1\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_n1\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_n1\n" } } */
/* { dg-final { scan-assembler-not "\tbl?\tstatic_n2\n" } } */
/* { dg-final { scan-assembler "\tbl\tstatic_n3\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_n3\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_n3\n" } } */
/* { dg-final { scan-assembler "\tbl\tstatic_l1\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_l1\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_l1\n" } } */
/* { dg-final { scan-assembler-not "\tbl?\tstatic_l2\n" } } */
/* { dg-final { scan-assembler "\tbl\tstatic_l3\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_l3\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_l3\n" } } */
/* { dg-final { scan-assembler "\tbl\tstatic_s1\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_s1\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_s1\n" } } */
/* { dg-final { scan-assembler "\tbl\tstatic_s2\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_s2\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_s2\n" } } */
/* { dg-final { scan-assembler "\tbl\tstatic_s3\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_s3\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_s3\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/long-calls-3.c b/gcc/testsuite/gcc.target/arm/long-calls-3.c
index 92817156370..bd1891c008b 100644
--- a/gcc/testsuite/gcc.target/arm/long-calls-3.c
+++ b/gcc/testsuite/gcc.target/arm/long-calls-3.c
@@ -39,79 +39,88 @@ DO_TESTS_CALL_ATTR (static_, STATIC_CALL,)
/* Calls to remote_*, strong_* and weak_* should honor the call type
- sttribute, with "short" being the default. */
+ attribute, with "short" being the default.
-/* { dg-final { scan-assembler "\tbl\tremote_n1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tremote_n2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tremote_n3\\(PLT\\)\n" } } */
+ In the regular expressions below:
+
+ * The PLT marker is optional, even though we are using -fpic,
+ because it is not used (or required) on some targets.
-/* { dg-final { scan-assembler-not "\tbl\tremote_l1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl\tremote_l2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl\tremote_l3\\(PLT\\)\n" } } */
+ * We allow both "b" and "bl" in some cases to allow for the
+ possibility of sibling calls. As of this writing, GCC does not
+ use sibling calls in Thumb-2 mode. */
-/* { dg-final { scan-assembler "\tbl\tremote_s1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tremote_s2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tremote_s3\\(PLT\\)\n" } } */
+/* { dg-final { scan-assembler "\tbl\tremote_n1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tremote_n2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tremote_n3(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl\tremote_l1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl\tremote_l2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl\tremote_l3(\\(PLT\\))?\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstrong_n1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_n1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstrong_n2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_n2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstrong_n3\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_n3\\(PLT\\)\n" } } */
+/* { dg-final { scan-assembler "\tbl\tremote_s1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tremote_s2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tremote_s3(\\(PLT\\))?\n" } } */
-/* { dg-final { scan-assembler-not "\tbl\tstrong_l1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tstrong_l2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl\tstrong_l3\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstrong_s1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_s1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstrong_s2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_s2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstrong_s3\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_s3\\(PLT\\)\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstrong_n1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_n1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstrong_n2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_n2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstrong_n3(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_n3(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl\tstrong_l1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl?\tstrong_l2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl\tstrong_l3(\\(PLT\\))?\n" } } */
-/* { dg-final { scan-assembler "\tbl\tweak_n1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_n1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tweak_n2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_n2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tweak_n3\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_n3\\(PLT\\)\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstrong_s1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_s1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstrong_s2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_s2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstrong_s3(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_s3(\\(PLT\\))?\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tweak_l1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tweak_l2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tweak_l3\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tweak_s1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_s1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tweak_s2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_s2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tweak_s3\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_s3\\(PLT\\)\n" } } */
+/* { dg-final { scan-assembler "\tbl\tweak_n1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_n1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tweak_n2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_n2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tweak_n3(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_n3(\\(PLT\\))?\n" } } */
+
+/* { dg-final { scan-assembler-not "\tbl?\tweak_l1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl?\tweak_l2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl?\tweak_l3(\\(PLT\\))?\n" } } */
+
+/* { dg-final { scan-assembler "\tbl\tweak_s1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_s1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tweak_s2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_s2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tweak_s3(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_s3(\\(PLT\\))?\n" } } */
/* Calls to static_*2 calls should honor the call type attribute,
with "short" being the default. Calls to other static_* functions
should be short. */
-/* { dg-final { scan-assembler "\tbl\tstatic_n1(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_n1(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstatic_n2(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_n2(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstatic_n3(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_n3(\\(PLT\\))\n" } } */
-
-/* { dg-final { scan-assembler "\tbl\tstatic_l1(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_l1(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tstatic_l2(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstatic_l3(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_l3(\\(PLT\\))\n" } } */
-
-/* { dg-final { scan-assembler "\tbl\tstatic_s1(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_s1(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstatic_s2(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_s2(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstatic_s3(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_s3(\\(PLT\\))\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstatic_n1((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_n1((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstatic_n2((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_n2((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstatic_n3((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_n3((\\(PLT\\))?)\n" } } */
+
+/* { dg-final { scan-assembler "\tbl\tstatic_l1((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_l1((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler-not "\tbl?\tstatic_l2((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstatic_l3((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_l3((\\(PLT\\))?)\n" } } */
+
+/* { dg-final { scan-assembler "\tbl\tstatic_s1((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_s1((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstatic_s2((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_s2((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstatic_s3((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_s3((\\(PLT\\))?)\n" } } */
diff --git a/gcc/testsuite/gcc.target/arm/long-calls-4.c b/gcc/testsuite/gcc.target/arm/long-calls-4.c
index facf85c73b6..dc184b8f8be 100644
--- a/gcc/testsuite/gcc.target/arm/long-calls-4.c
+++ b/gcc/testsuite/gcc.target/arm/long-calls-4.c
@@ -39,72 +39,81 @@ DO_TESTS_CALL_ATTR (static_, STATIC_CALL,)
/* Calls to remote_*, strong_* and weak_* should honor the call type
- sttribute, with "long" being the default. */
+ attribute, with "long" being the default.
-/* { dg-final { scan-assembler-not "\tbl\tremote_n1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl\tremote_n2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl\tremote_n3\\(PLT\\)\n" } } */
+ In the regular expressions below:
+
+ * The PLT marker is optional, even though we are using -fpic,
+ because it is not used (or required) on some targets.
-/* { dg-final { scan-assembler-not "\tbl\tremote_l1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl\tremote_l2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl\tremote_l3\\(PLT\\)\n" } } */
+ * We allow both "b" and "bl" in some cases to allow for the
+ possibility of sibling calls. As of this writing, GCC does not
+ use sibling calls in Thumb-2 mode. */
-/* { dg-final { scan-assembler "\tbl\tremote_s1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tremote_s2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tremote_s3\\(PLT\\)\n" } } */
+/* { dg-final { scan-assembler-not "\tbl\tremote_n1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl\tremote_n2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl\tremote_n3(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl\tremote_l1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl\tremote_l2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl\tremote_l3(\\(PLT\\))?\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tstrong_n1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tstrong_n2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tstrong_n3\\(PLT\\)\n" } } */
+/* { dg-final { scan-assembler "\tbl\tremote_s1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tremote_s2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tremote_s3(\\(PLT\\))?\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tstrong_l1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tstrong_l2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tstrong_l3\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstrong_s1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_s1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstrong_s2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_s2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstrong_s3\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tstrong_s3\\(PLT\\)\n" } } */
+/* { dg-final { scan-assembler-not "\tbl?\tstrong_n1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl?\tstrong_n2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl?\tstrong_n3(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl?\tstrong_l1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl?\tstrong_l2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl?\tstrong_l3(\\(PLT\\))?\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tweak_n1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tweak_n2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tweak_n3\\(PLT\\)\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstrong_s1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_s1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstrong_s2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_s2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstrong_s3(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstrong_s3(\\(PLT\\))?\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tweak_l1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tweak_l2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tweak_l3\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tweak_s1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_s1\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tweak_s2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_s2\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tbl\tweak_s3\\(PLT\\)\n" } } */
-/* { dg-final { scan-assembler "\tb\tweak_s3\\(PLT\\)\n" } } */
+/* { dg-final { scan-assembler-not "\tbl?\tweak_n1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl?\tweak_n2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl?\tweak_n3(\\(PLT\\))?\n" } } */
+
+/* { dg-final { scan-assembler-not "\tbl?\tweak_l1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl?\tweak_l2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler-not "\tbl?\tweak_l3(\\(PLT\\))?\n" } } */
+
+/* { dg-final { scan-assembler "\tbl\tweak_s1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_s1(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tweak_s2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_s2(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl\tweak_s3(\\(PLT\\))?\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tweak_s3(\\(PLT\\))?\n" } } */
/* Calls to static_*2 calls should honor the call type attribute,
with "long" being the default. Calls to other static_* functions
should be short. */
-/* { dg-final { scan-assembler "\tbl\tstatic_n1(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_n1(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tstatic_n2(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstatic_n3(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_n3(\\(PLT\\))\n" } } */
-
-/* { dg-final { scan-assembler "\tbl\tstatic_l1(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_l1(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler-not "\tbl?\tstatic_l2(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstatic_l3(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_l3(\\(PLT\\))\n" } } */
-
-/* { dg-final { scan-assembler "\tbl\tstatic_s1(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_s1(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstatic_s2(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_s2(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tbl\tstatic_s3(\\(PLT\\))\n" } } */
-/* { dg-final { scan-assembler "\tb\tstatic_s3(\\(PLT\\))\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstatic_n1((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_n1((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler-not "\tbl?\tstatic_n2((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstatic_n3((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_n3((\\(PLT\\))?)\n" } } */
+
+/* { dg-final { scan-assembler "\tbl\tstatic_l1((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_l1((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler-not "\tbl?\tstatic_l2((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstatic_l3((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_l3((\\(PLT\\))?)\n" } } */
+
+/* { dg-final { scan-assembler "\tbl\tstatic_s1((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_s1((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstatic_s2((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_s2((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl\tstatic_s3((\\(PLT\\))?)\n" } } */
+/* { dg-final { scan-assembler "\tbl?\tstatic_s3((\\(PLT\\))?)\n" } } */
diff --git a/gcc/testsuite/gcc.target/i386/sse-10.c b/gcc/testsuite/gcc.target/i386/sse-10.c
index b5bc8f66b44..5cf0714f07b 100644
--- a/gcc/testsuite/gcc.target/i386/sse-10.c
+++ b/gcc/testsuite/gcc.target/i386/sse-10.c
@@ -1,6 +1,6 @@
/* PR 17930 */
/* { dg-do run } */
-/* { dg-options "-O1 -msse2 -mfpmath=sse -mno-accumulate-outgoing-args -fno-omit-frame-pointer" } */
+/* { dg-options "-O1 -msse2 -mfpmath=sse -mno-accumulate-outgoing-args -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer" } */
/* { dg-options "-O1 -msse2 -mfpmath=sse -fno-omit-frame-pointer" { target *-*-mingw* *-*-cygwin* } } */
#include "sse2-check.h"
diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp
index e1496d9d6a7..c5d6089a964 100644
--- a/gcc/testsuite/gcc.target/mips/mips.exp
+++ b/gcc/testsuite/gcc.target/mips/mips.exp
@@ -269,15 +269,14 @@ set mips_abi_groups {
# on a target that supports OPTION.
set mips_option_tests(-mips16) {
move $2,$31
- jal 1f
- b 2f
- .align 2
+ bal 1f
.set mips16
-1:
jr $31
.set nomips16
.align 2
-2:
+1:
+ ori $3,$31,1
+ jalr $3
move $31,$2
}
set mips_option_tests(-mpaired-single) {
diff --git a/gcc/testsuite/gcc.target/powerpc/20030218-1.c b/gcc/testsuite/gcc.target/powerpc/20030218-1.c
index 024f637f8ec..2a1c4e6d253 100644
--- a/gcc/testsuite/gcc.target/powerpc/20030218-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/20030218-1.c
@@ -1,5 +1,6 @@
-/* { dg-do compile { target powerpc-*-eabi* } } */
-/* { dg-options "-mspe=yes -mfloat-gprs=single" } */
+/* { dg-do compile } */
+/* { dg-options "-mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single" } */
+/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */
/* Test vectors that can interconvert without a cast. */
@@ -19,7 +20,7 @@ main (void)
/* Just because this is a V2SI, it doesn't make it an opaque. */
vint = vshort; /* { dg-message "note: use -flax-vector-conversions to permit conversions between vectors with differing element types or numbers of subparts" } */
- /* { dg-error "incompatible types when assigning" "" { target *-*-* } 21 } */
+ /* { dg-error "incompatible types when assigning" "" { target *-*-* } 22 } */
return 0;
}
diff --git a/gcc/testsuite/gcc.target/powerpc/20030505.c b/gcc/testsuite/gcc.target/powerpc/20030505.c
index a8283934d71..2bef590bf7b 100644
--- a/gcc/testsuite/gcc.target/powerpc/20030505.c
+++ b/gcc/testsuite/gcc.target/powerpc/20030505.c
@@ -1,5 +1,6 @@
-/* { dg-do compile { target powerpc-*-eabi* } } */
+/* { dg-do compile } */
/* { dg-options "-W -mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single" } */
+/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */
#define __vector __attribute__((vector_size(8)))
diff --git a/gcc/testsuite/gcc.target/powerpc/20081204-1.c b/gcc/testsuite/gcc.target/powerpc/20081204-1.c
index ba4df8f3e29..8a973d0ec52 100644
--- a/gcc/testsuite/gcc.target/powerpc/20081204-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/20081204-1.c
@@ -2,6 +2,8 @@
TARGET_HARD_FLOAT && !TARGET_FPRS. */
/* { dg-do compile } */
/* { dg-options "-mcpu=750 -mfloat-gprs=single" } */
+/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */
+
static int comp(const void *a,const void *b){
return (*(float *)a<*(float *)b)-(*(float *)a>*(float *)b);
}
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-1.c b/gcc/testsuite/gcc.target/powerpc/altivec-1.c
index f235e7b57ac..b1809fe2c9c 100644
--- a/gcc/testsuite/gcc.target/powerpc/altivec-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-1.c
@@ -1,11 +1,11 @@
-/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-maltivec" } */
/* Program to test PowerPC AltiVec instructions. */
#include <altivec.h>
-#include "altivec_check.h"
extern void abort (void);
@@ -24,8 +24,6 @@ vector float f, g, h;
int main ()
{
- altivec_check(); /* Exits if AltiVec not supported */
-
k = vec_add (a1, a2);
if (!vec_all_eq (addi, k))
abort ();
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-10.c b/gcc/testsuite/gcc.target/powerpc/altivec-10.c
index 82b3f45a391..f532eebbfab 100644
--- a/gcc/testsuite/gcc.target/powerpc/altivec-10.c
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-10.c
@@ -1,11 +1,12 @@
-/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-maltivec -mabi=altivec -fno-inline" } */
#include <altivec.h>
-#include <signal.h>
-#include "altivec_check.h"
+extern void exit (int);
+extern void abort (void);
typedef union
{
@@ -72,8 +73,6 @@ check_cmple()
int
main()
{
- altivec_check ();
-
check_cmple ();
check_vec_all_num ();
exit (0);
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-12.c b/gcc/testsuite/gcc.target/powerpc/altivec-12.c
index 296a3f7510a..39d26940d4e 100644
--- a/gcc/testsuite/gcc.target/powerpc/altivec-12.c
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-12.c
@@ -1,11 +1,11 @@
-/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-maltivec" } */
/* Program to test PowerPC AltiVec instructions. */
#include <altivec.h>
-#include "altivec_check.h"
extern void abort (void);
#define CHECK_IF(E) if(!(E)) abort()
@@ -26,9 +26,6 @@ vector float f, g, h;
int main ()
{
-
- altivec_check(); /* Exit if AltiVec not available. */
-
k = vec_add (a1, a2);
CHECK_IF (vec_all_eq (addi, k));
CHECK_IF (vec_all_ge (addi, k));
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-24.c b/gcc/testsuite/gcc.target/powerpc/altivec-24.c
index cb1a66832e7..d296fe24658 100644
--- a/gcc/testsuite/gcc.target/powerpc/altivec-24.c
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-24.c
@@ -1,9 +1,9 @@
-/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-maltivec" } */
#include <altivec.h>
-#include "altivec_check.h"
extern void abort (void);
@@ -28,7 +28,6 @@ int verify (void)
int main (void)
{
- altivec_check (); /* Exit if hardware doesn't support AltiVec. */
initialize (MAGIC_NUMBER);
verify ();
return 0;
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-3.c b/gcc/testsuite/gcc.target/powerpc/altivec-3.c
index 17f62fd8f03..d388ad299a4 100644
--- a/gcc/testsuite/gcc.target/powerpc/altivec-3.c
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-3.c
@@ -1,8 +1,10 @@
-/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-maltivec" } */
-#include "altivec_check.h"
+extern void exit (int);
+extern void abort (void);
typedef int int4 __attribute__ ((vector_size (16)));
typedef float float4 __attribute__ ((vector_size (16)));
@@ -73,7 +75,6 @@ main1 ()
int
main ()
{
- altivec_check ();
main1 ();
exit (0);
}
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-cell-2.c b/gcc/testsuite/gcc.target/powerpc/altivec-cell-2.c
index b9c7c90b303..fdb375c9efe 100644
--- a/gcc/testsuite/gcc.target/powerpc/altivec-cell-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-cell-2.c
@@ -1,9 +1,9 @@
-/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-maltivec" } */
/* Test the vec_extract VMX intrinsics. */
#include <altivec.h>
-#include "altivec_check.h"
extern void abort (void);
@@ -137,6 +137,5 @@ int main1(void)
int main(void)
{
- altivec_check(); /* Exits if AltiVec not supported */
return main1 ();
}
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-cell-3.c b/gcc/testsuite/gcc.target/powerpc/altivec-cell-3.c
index abaf56f2770..b941ab186fa 100644
--- a/gcc/testsuite/gcc.target/powerpc/altivec-cell-3.c
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-cell-3.c
@@ -1,9 +1,9 @@
-/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-maltivec" } */
/* Test the vec_splats and vec_promote VMX intrinsics. */
#include <altivec.h>
-#include "altivec_check.h"
extern void abort (void);
@@ -33,6 +33,5 @@ int main1(int t)
int main(void)
{
- altivec_check(); /* Exits if AltiVec not supported */
return main1 (0);
}
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-cell-4.c b/gcc/testsuite/gcc.target/powerpc/altivec-cell-4.c
index b800ea51105..c694691d475 100644
--- a/gcc/testsuite/gcc.target/powerpc/altivec-cell-4.c
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-cell-4.c
@@ -1,10 +1,10 @@
-/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-maltivec" } */
/* Test the vec_splats and vec_promote VMX intrinsics. */
#include <altivec.h>
-#include "altivec_check.h"
extern void abort (void);
@@ -38,6 +38,5 @@ int main1(int t)
int main(void)
{
- altivec_check(); /* Exits if AltiVec not supported */
return main1 (0);
}
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-cell-8.c b/gcc/testsuite/gcc.target/powerpc/altivec-cell-8.c
index 12e13e00aa8..dda5eb0c114 100644
--- a/gcc/testsuite/gcc.target/powerpc/altivec-cell-8.c
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-cell-8.c
@@ -1,9 +1,11 @@
-/* { dg-do run } */
+/* { dg-do run { target { powerpc*-*-* && cell_hw } } } */
+/* { dg-do compile { target { powerpc*-*-* && { ! cell_hw } } } } */
/* { dg-require-effective-target powerpc_ppu_ok } */
/* { dg-options "-O2 -maltivec -mabi=altivec -mcpu=cell" } */
#include <altivec.h>
#include <string.h>
-#include "altivec_check.h"
+
+extern void abort (void);
typedef short int sint16;
typedef signed char int8;
@@ -51,6 +53,5 @@ return 0;
int main(void)
{
- altivec_cell_check ();
return main1();
}
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-consts.c b/gcc/testsuite/gcc.target/powerpc/altivec-consts.c
index e06a5286b17..2c5bc99cff8 100644
--- a/gcc/testsuite/gcc.target/powerpc/altivec-consts.c
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-consts.c
@@ -1,11 +1,10 @@
-/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-maltivec -mabi=altivec -O2" } */
/* Check that "easy" AltiVec constants are correctly synthesized. */
-#include "altivec_check.h"
-
extern void abort (void);
typedef __attribute__ ((vector_size (16))) unsigned char v16qi;
@@ -283,8 +282,6 @@ void v4si_vspltisw_neg_addself ()
int main ()
{
- altivec_check (); /* Exit if hardware doesn't support AltiVec. */
-
v16qi_vspltisb ();
v16qi_vspltisb_neg ();
v16qi_vspltisb_addself ();
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-macros.c b/gcc/testsuite/gcc.target/powerpc/altivec-macros.c
index 8ea8df241db..c07eaa36a49 100644
--- a/gcc/testsuite/gcc.target/powerpc/altivec-macros.c
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-macros.c
@@ -1,6 +1,7 @@
/* Copyright (C) 2007 Free Software Foundation, Inc. */
/* { dg-do preprocess } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-maltivec" } */
/* Conditional macros should not be expanded by pragmas. */
@@ -48,16 +49,16 @@ _Pragma ("__vector")
#define pixel newer_pixel
#define bool newer_bool
-/* { dg-warning "redefined" "__vector redefined" { target *-*-* } 44 } */
-/* { dg-warning "redefined" "__pixel redefined" { target *-*-* } 45 } */
-/* { dg-warning "redefined" "__bool redefined" { target *-*-* } 46 } */
-/* { dg-warning "redefined" "vector redefined" { target *-*-* } 47 } */
-/* { dg-warning "redefined" "pixel redefined" { target *-*-* } 48 } */
-/* { dg-warning "redefined" "bool redefined" { target *-*-* } 49 } */
-
-/* { dg-message "location of the previous" "prev __vector defn" { target *-*-* } 24 } */
-/* { dg-message "location of the previous" "prev __pixel defn" { target *-*-* } 27 } */
-/* { dg-message "location of the previous" "prev __bool defn" { target *-*-* } 30 } */
-/* { dg-message "location of the previous" "prev vector defn" { target *-*-* } 33 } */
-/* { dg-message "location of the previous" "prev pixel defn" { target *-*-* } 36 } */
-/* { dg-message "location of the previous" "prev bool defn" { target *-*-* } 39 } */
+/* { dg-warning "redefined" "__vector redefined" { target *-*-* } 45 } */
+/* { dg-warning "redefined" "__pixel redefined" { target *-*-* } 46 } */
+/* { dg-warning "redefined" "__bool redefined" { target *-*-* } 47 } */
+/* { dg-warning "redefined" "vector redefined" { target *-*-* } 48 } */
+/* { dg-warning "redefined" "pixel redefined" { target *-*-* } 49 } */
+/* { dg-warning "redefined" "bool redefined" { target *-*-* } 50 } */
+
+/* { dg-message "location of the previous" "prev __vector defn" { target *-*-* } 25 } */
+/* { dg-message "location of the previous" "prev __pixel defn" { target *-*-* } 28 } */
+/* { dg-message "location of the previous" "prev __bool defn" { target *-*-* } 31 } */
+/* { dg-message "location of the previous" "prev vector defn" { target *-*-* } 34 } */
+/* { dg-message "location of the previous" "prev pixel defn" { target *-*-* } 37 } */
+/* { dg-message "location of the previous" "prev bool defn" { target *-*-* } 40 } */
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-varargs-1.c b/gcc/testsuite/gcc.target/powerpc/altivec-varargs-1.c
index 2aa54a912a5..1349ae590d9 100644
--- a/gcc/testsuite/gcc.target/powerpc/altivec-varargs-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-varargs-1.c
@@ -1,11 +1,12 @@
-/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-maltivec -mabi=altivec -fno-inline" } */
#include <stdarg.h>
-#include <signal.h>
-#include "altivec_check.h"
+extern void exit (int);
+extern void abort (void);
#define vector __attribute__((vector_size (16)))
@@ -77,8 +78,5 @@ int main1(void)
int main (void)
{
- /* Exit on systems without AltiVec. */
- altivec_check ();
-
return main1 ();
}
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec-vec-merge.c b/gcc/testsuite/gcc.target/powerpc/altivec-vec-merge.c
index e6027bdeff8..3689f97490c 100644
--- a/gcc/testsuite/gcc.target/powerpc/altivec-vec-merge.c
+++ b/gcc/testsuite/gcc.target/powerpc/altivec-vec-merge.c
@@ -1,9 +1,9 @@
-/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-maltivec -O2" } */
#include <altivec.h>
-#include "altivec_check.h"
int printf(const char * , ...);
extern void abort();
@@ -600,7 +600,6 @@ int main(int argc, char **argv)
{
char toto[32] __attribute__((aligned(16)));
- altivec_check (); /* Exit if hardware doesn't support AltiVec. */
foo(toto, toto, 0, 0);
return 0;
}
diff --git a/gcc/testsuite/gcc.target/powerpc/altivec_check.h b/gcc/testsuite/gcc.target/powerpc/altivec_check.h
deleted file mode 100644
index d966e238a10..00000000000
--- a/gcc/testsuite/gcc.target/powerpc/altivec_check.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* A runtime check for AltiVec capability. */
-/* Contributed by Ziemowit Laski <zlaski@apple.com> */
-
-#include <signal.h>
-extern void exit (int);
-extern void abort (void);
-
-void
-sig_ill_handler (int sig)
-{
- exit (0);
-}
-
-void altivec_check(void) {
-
- /* Exit on systems without AltiVec. */
- signal (SIGILL, sig_ill_handler);
-#ifdef __MACH__
- asm volatile ("vor v0,v0,v0");
-#else
- asm volatile ("vor 0,0,0");
-#endif
- signal (SIGILL, SIG_DFL);
-}
-
-void altivec_cell_check (void)
-{
-#ifdef __PPU__
- /* Exit on systems without the Cell Altivec instructions. */
- signal (SIGILL, sig_ill_handler);
-#ifdef __MACH__
- asm volatile ("vor v0,v0,v0");
- asm volatile ("lvlx v0,r0,r0");
-#else
- asm volatile ("vor 0,0,0");
- asm volatile ("lvlx 0,0,0");
-#endif
- signal (SIGILL, SIG_DFL);
-#else
- /* altivec_cell_check shouldn't be called without -mcpu=cell. */
- abort ();
-#endif
-}
diff --git a/gcc/testsuite/gcc.target/powerpc/ppc-spe.c b/gcc/testsuite/gcc.target/powerpc/ppc-spe.c
index 841073b22b7..b5643943340 100644
--- a/gcc/testsuite/gcc.target/powerpc/ppc-spe.c
+++ b/gcc/testsuite/gcc.target/powerpc/ppc-spe.c
@@ -1,5 +1,6 @@
-/* { dg-do compile { target powerpc-*-eabi* } } */
+/* { dg-do compile } */
/* { dg-options "-mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single -O0" } */
+/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */
/* (Test with -O0 so we don't optimize any of them away). */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr35907.c b/gcc/testsuite/gcc.target/powerpc/pr35907.c
index e1749dea8c9..7d5465ea151 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr35907.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr35907.c
@@ -1,10 +1,9 @@
/* PR target/35907 */
-/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-do compile { target { powerpc*-*-* && { ! vmx_hw } } } } */
/* { dg-require-effective-target powerpc_altivec_ok } */
/* { dg-options "-O2 -maltivec" } */
-#include "altivec_check.h"
-
#define vector __attribute__((vector_size (16)))
union
{
@@ -53,7 +52,6 @@ test (void)
int
main ()
{
- altivec_check ();
test ();
return 0;
}
diff --git a/gcc/testsuite/gcc.target/powerpc/spe-vector-memcpy.c b/gcc/testsuite/gcc.target/powerpc/spe-vector-memcpy.c
index d12f6696eb0..09f8134829c 100644
--- a/gcc/testsuite/gcc.target/powerpc/spe-vector-memcpy.c
+++ b/gcc/testsuite/gcc.target/powerpc/spe-vector-memcpy.c
@@ -1,6 +1,6 @@
-/* { dg-do compile { target powerpc*-*-* } } */
-/* { dg-require-effective-target powerpc_spe } */
-/* { dg-options "-O -mspe=yes" } */
+/* { dg-do compile } */
+/* { dg-options "-O -mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single" } */
+/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */
/* { dg-final { scan-assembler "evstdd" } } */
void foo(void)
diff --git a/gcc/testsuite/gcc.target/powerpc/spe1.c b/gcc/testsuite/gcc.target/powerpc/spe1.c
index 9803d8fdb7f..ddbb5a6e1c9 100644
--- a/gcc/testsuite/gcc.target/powerpc/spe1.c
+++ b/gcc/testsuite/gcc.target/powerpc/spe1.c
@@ -1,5 +1,6 @@
-/* { dg-do compile { target powerpc-*-eabi* } } */
+/* { dg-do compile } */
/* { dg-options "-mcpu=8540 -mspe -mabi=spe -mfloat-gprs=single -O0" } */
+/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */
/* (Test with -O0 so we don't optimize any of them away). */
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 1aa1855a1ab..aaefa60cbcb 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -905,6 +905,40 @@ proc check_vmx_hw_available { } {
}]
}
+# Return 1 if the target supports executing AltiVec and Cell PPU
+# instructions, 0 otherwise. Cache the result.
+
+proc check_effective_target_cell_hw { } {
+ return [check_cached_effective_target cell_hw_available {
+ # Some simulators are known to not support VMX and PPU instructions.
+ if { [istarget powerpc-*-eabi*] } {
+ expr 0
+ } else {
+ # Most targets don't require special flags for this test
+ # case, but Darwin and AIX do.
+ if { [istarget *-*-darwin*]
+ || [istarget *-*-aix*] } {
+ set options "-maltivec -mcpu=cell"
+ } else {
+ set options "-mcpu=cell"
+ }
+ check_runtime_nocache cell_hw_available {
+ int main()
+ {
+ #ifdef __MACH__
+ asm volatile ("vor v0,v0,v0");
+ asm volatile ("lvlx v0,r0,r0");
+ #else
+ asm volatile ("vor 0,0,0");
+ asm volatile ("lvlx 0,0,0");
+ #endif
+ return 0;
+ }
+ } $options
+ }
+ }]
+}
+
# Return 1 if the target supports executing 64-bit instructions, 0
# otherwise. Cache the result.
@@ -1501,6 +1535,23 @@ proc check_effective_target_powerpc_spu { } {
}
}
+# Return 1 if this is a PowerPC SPE target. The check includes options
+# specified by dg-options for this test, so don't cache the result.
+
+proc check_effective_target_powerpc_spe_nocache { } {
+ if { [istarget powerpc*-*-*] } {
+ return [check_no_compiler_messages_nocache powerpc_spe object {
+ #ifndef __SPE__
+ #error not SPE
+ #else
+ int dummy;
+ #endif
+ } [current_compiler_flags]]
+ } else {
+ return 0
+ }
+}
+
# Return 1 if this is a PowerPC target with SPE enabled.
proc check_effective_target_powerpc_spe { } {
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 3d64c1cbd33..8b49556b3c0 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -1129,6 +1129,8 @@ build_pred_graph (void)
}
else if (rhs.type == ADDRESSOF)
{
+ varinfo_t v;
+
/* x = &y */
if (graph->points_to[lhsvar] == NULL)
graph->points_to[lhsvar] = BITMAP_ALLOC (&predbitmap_obstack);
@@ -1141,7 +1143,19 @@ build_pred_graph (void)
/* Implicitly, *x = y */
add_implicit_graph_edge (graph, FIRST_REF_NODE + lhsvar, rhsvar);
+ /* All related variables are no longer direct nodes. */
RESET_BIT (graph->direct_nodes, rhsvar);
+ v = get_varinfo (rhsvar);
+ if (!v->is_full_var)
+ {
+ v = lookup_vi_for_tree (v->decl);
+ do
+ {
+ RESET_BIT (graph->direct_nodes, v->id);
+ v = v->next;
+ }
+ while (v != NULL);
+ }
bitmap_set_bit (graph->address_taken, rhsvar);
}
else if (lhsvar > anything_id
@@ -4561,6 +4575,16 @@ intra_create_variable_infos (void)
}
}
+ /* Add a constraint for a result decl that is passed by reference. */
+ if (DECL_RESULT (cfun->decl)
+ && DECL_BY_REFERENCE (DECL_RESULT (cfun->decl)))
+ {
+ varinfo_t p, result_vi = get_vi_for_tree (DECL_RESULT (cfun->decl));
+
+ for (p = result_vi; p; p = p->next)
+ make_constraint_from (p, nonlocal_id);
+ }
+
/* Add a constraint for the incoming static chain parameter. */
if (cfun->static_chain_decl != NULL_TREE)
{
@@ -4735,7 +4759,7 @@ emit_alias_warning (tree ptr)
{
gimple use;
imm_use_iterator ui;
- unsigned warned = 0;
+ bool warned = false;
FOR_EACH_IMM_USE_STMT (use, ui, ptr)
{
@@ -4773,13 +4797,12 @@ emit_alias_warning (tree ptr)
&& !TREE_NO_WARNING (deref))
{
TREE_NO_WARNING (deref) = 1;
- warning_at (gimple_location (use), OPT_Wstrict_aliasing,
- "dereferencing pointer %qD does break strict-aliasing "
- "rules", SSA_NAME_VAR (ptr));
- ++warned;
+ warned |= warning_at (gimple_location (use), OPT_Wstrict_aliasing,
+ "dereferencing pointer %qD does break "
+ "strict-aliasing rules", SSA_NAME_VAR (ptr));
}
}
- if (warned > 0)
+ if (warned)
{
bitmap visited = BITMAP_ALLOC (NULL);
emit_pointer_definition (ptr, visited);