summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-15 17:11:32 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-15 17:11:32 +0000
commit0fb3af46a9812808184394522ff6d65089d3f9bb (patch)
tree4758c5c96ba58a9277e874c67cdf097af9b94edd /gcc
parentd0d9fa3b225da0716148b9879b699c6014a626c2 (diff)
downloadgcc-0fb3af46a9812808184394522ff6d65089d3f9bb.tar.gz
2012-10-15 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 192465 using svnmerge.py git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@192466 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog683
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/acinclude.m46
-rw-r--r--gcc/alias.c27
-rw-r--r--gcc/attribs.c6
-rw-r--r--gcc/builtins.c46
-rw-r--r--gcc/builtins.def11
-rw-r--r--gcc/c-family/ChangeLog26
-rw-r--r--gcc/c-family/c-ada-spec.c12
-rw-r--r--gcc/c-family/c-common.c168
-rw-r--r--gcc/c-family/c-common.h8
-rw-r--r--gcc/c/ChangeLog13
-rw-r--r--gcc/c/c-parser.c71
-rw-r--r--gcc/cfgloop.h3
-rw-r--r--gcc/cfgloopanal.c37
-rw-r--r--gcc/combine.c12
-rw-r--r--gcc/config/alpha/alpha.c18
-rw-r--r--gcc/config/alpha/alpha.md2703
-rw-r--r--gcc/config/alpha/sync.md70
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.c27
-rw-r--r--gcc/config/arm/arm.h5
-rw-r--r--gcc/config/arm/arm.md10
-rw-r--r--gcc/config/i386/bdver1.md36
-rw-r--r--gcc/config/mips/mips-protos.h2
-rw-r--r--gcc/config/mips/mips.c13
-rw-r--r--gcc/config/mips/mips.md10
-rw-r--r--gcc/config/mmix/mmix.c26
-rw-r--r--gcc/config/rs6000/predicates.md1
-rw-r--r--gcc/config/rs6000/rs6000-c.c9
-rw-r--r--gcc/config/rs6000/rs6000-protos.h7
-rw-r--r--gcc/config/rs6000/rs6000.c229
-rw-r--r--gcc/config/rs6000/rs6000.h3
-rw-r--r--gcc/config/rs6000/rs6000.md2
-rw-r--r--gcc/config/rs6000/rs6000.opt2
-rw-r--r--gcc/config/s390/s390.c131
-rw-r--r--gcc/config/s390/s390.md25
-rw-r--r--gcc/config/sh/predicates.md37
-rw-r--r--gcc/config/sh/sh-protos.h1
-rw-r--r--gcc/config/sh/sh.c74
-rw-r--r--gcc/config/sh/sh.md348
-rw-r--r--gcc/config/xtensa/xtensa.c38
-rw-r--r--gcc/config/xtensa/xtensa.md4
-rwxr-xr-xgcc/configure25
-rw-r--r--gcc/configure.ac19
-rw-r--r--gcc/cp/ChangeLog85
-rw-r--r--gcc/cp/call.c2
-rw-r--r--gcc/cp/class.c90
-rw-r--r--gcc/cp/cp-tree.h30
-rw-r--r--gcc/cp/decl.c10
-rw-r--r--gcc/cp/error.c5
-rw-r--r--gcc/cp/init.c3
-rw-r--r--gcc/cp/method.c217
-rw-r--r--gcc/cp/name-lookup.c13
-rw-r--r--gcc/cp/parser.c40
-rw-r--r--gcc/cp/pt.c75
-rw-r--r--gcc/cp/semantics.c28
-rw-r--r--gcc/cp/tree.c2
-rw-r--r--gcc/cp/typeck.c4
-rw-r--r--gcc/data-streamer-in.c29
-rw-r--r--gcc/data-streamer-out.c33
-rw-r--r--gcc/data-streamer.h7
-rw-r--r--gcc/df-problems.c36
-rw-r--r--gcc/df.h40
-rw-r--r--gcc/doc/extend.texi2
-rw-r--r--gcc/doc/generic.texi25
-rw-r--r--gcc/doc/gty.texi21
-rw-r--r--gcc/doc/md.texi28
-rw-r--r--gcc/expr.c11
-rw-r--r--gcc/fold-const.c34
-rw-r--r--gcc/fortran/ChangeLog12
-rw-r--r--gcc/fortran/interface.c13
-rw-r--r--gcc/fortran/trans-stmt.c12
-rw-r--r--gcc/gcov.c2
-rw-r--r--gcc/gengtype-lex.l25
-rw-r--r--gcc/gengtype-parse.c186
-rw-r--r--gcc/gengtype-state.c6
-rw-r--r--gcc/gengtype.c17
-rw-r--r--gcc/gengtype.h65
-rw-r--r--gcc/genoutput.c66
-rw-r--r--gcc/gimple-streamer-in.c5
-rw-r--r--gcc/gimple-streamer-out.c8
-rw-r--r--gcc/gimplify.c1
-rw-r--r--gcc/ipa-prop.c14
-rw-r--r--gcc/ira-build.c142
-rw-r--r--gcc/ira-color.c8
-rw-r--r--gcc/ira-conflicts.c2
-rw-r--r--gcc/ira-emit.c14
-rw-r--r--gcc/ira-lives.c15
-rw-r--r--gcc/ira.c47
-rw-r--r--gcc/loop-iv.c56
-rw-r--r--gcc/loop-unroll.c63
-rw-r--r--gcc/lto-streamer-in.c44
-rw-r--r--gcc/lto-streamer-out.c41
-rw-r--r--gcc/lto-streamer.c2
-rw-r--r--gcc/lto-streamer.h4
-rw-r--r--gcc/lto/ChangeLog7
-rw-r--r--gcc/lto/lto.c15
-rw-r--r--gcc/optabs.c37
-rw-r--r--gcc/optabs.def3
-rw-r--r--gcc/simplify-rtx.c9
-rw-r--r--gcc/streamer-hooks.h20
-rw-r--r--gcc/testsuite/ChangeLog237
-rw-r--r--gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess1.c161
-rw-r--r--gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess2.c482
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-24.C24
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto35.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/decltype45.C40
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/gen-attrs-36.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/gen-attrs-37.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/gen-attrs-8.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor1.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor10.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor11.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor12.C26
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor13.C22
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor2.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor3.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor4.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor5.C21
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor6.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor7.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor8.C20
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor9.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist67.C27
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice9.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr52744.C83
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/weak5.C12
-rw-r--r--gcc/testsuite/g++.dg/gomp/tls-5.C3
-rw-r--r--gcc/testsuite/g++.dg/init/bitfield3.C11
-rw-r--r--gcc/testsuite/g++.dg/opt/pr52643.C64
-rw-r--r--gcc/testsuite/g++.dg/parse/friend-main.C30
-rw-r--r--gcc/testsuite/g++.dg/parse/pr43765.C14
-rw-r--r--gcc/testsuite/g++.dg/parse/tmpl-outside1.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/tmpl-outside2.C19
-rw-r--r--gcc/testsuite/g++.dg/pr53055.C5
-rw-r--r--gcc/testsuite/g++.dg/template/crash113.C50
-rw-r--r--gcc/testsuite/g++.dg/template/qualttp18.C2
-rw-r--r--gcc/testsuite/g++.dg/tls/static2.C18
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local7.C2
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local7g.C2
-rw-r--r--gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C112
-rw-r--r--gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C116
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memtemp87.C3
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/overload13.C2
-rw-r--r--gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c456
-rw-r--r--gcc/testsuite/gcc.dg/pr44194-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr53060.c3
-rw-r--r--gcc/testsuite/gcc.dg/pr54782.c1
-rw-r--r--gcc/testsuite/gcc.dg/pr54919.c27
-rw-r--r--gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c112
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr54877.c23
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr54894.c27
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr54920.c13
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr54915.c12
-rw-r--r--gcc/testsuite/gcc.dg/unroll_5.c25
-rw-r--r--gcc/testsuite/gcc.dg/vect/nodump-forwprop-22.c (renamed from gcc/testsuite/gcc.dg/tree-ssa/forwprop-22.c)2
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr48765.c5
-rw-r--r--gcc/testsuite/gcc.dg/webizer.c35
-rw-r--r--gcc/testsuite/gcc.target/arm/div64-unwinding.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/pr53397-1.c (renamed from gcc/testsuite/gcc.dg/pr53397-1.c)4
-rw-r--r--gcc/testsuite/gcc.target/i386/pr53397-2.c (renamed from gcc/testsuite/gcc.dg/pr53397-2.c)4
-rw-r--r--gcc/testsuite/gcc.target/mips/mips32-dsp-accinit-2.c3
-rw-r--r--gcc/testsuite/gcc.target/sh/pr51244-13.c85
-rw-r--r--gcc/testsuite/gcc.target/sh/pr51244-14.c107
-rw-r--r--gcc/testsuite/gcc.target/sh/pr51244-15.c71
-rw-r--r--gcc/testsuite/gcc.target/sh/pr51244-16.c11
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54602-1.c15
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54602-2.c15
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54602-3.c12
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54602-4.c15
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54680.c66
-rw-r--r--gcc/testsuite/gfortran.dg/class_allocate_13.f9031
-rw-r--r--gcc/testsuite/gfortran.dg/dummy_procedure_9.f9037
-rw-r--r--gcc/testsuite/gnat.dg/unchecked_convert9.adb15
-rw-r--r--gcc/testsuite/gnat.dg/unchecked_convert9.ads20
-rw-r--r--gcc/testsuite/lib/target-supports.exp3
-rw-r--r--gcc/testsuite/obj-c++.dg/tls/init-2.mm6
-rw-r--r--gcc/tree-ssa-forwprop.c2
-rw-r--r--gcc/tree-ssa-loop-niter.c4
-rw-r--r--gcc/tree-ssa-pre.c2
-rw-r--r--gcc/tree-ssa-threadupdate.c12
-rw-r--r--gcc/tree-streamer-in.c180
-rw-r--r--gcc/tree-streamer-out.c166
-rw-r--r--gcc/tree-streamer.h6
-rw-r--r--gcc/tree-vect-loop.c2
-rw-r--r--gcc/tree-vect-stmts.c10
-rw-r--r--gcc/tree.def7
-rw-r--r--gcc/web.c32
191 files changed, 7201 insertions, 3132 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 153abd42e53..20ed440d22d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,7 +1,670 @@
+2012-10-15 Dodji Seketeli <dodji@redhat.com>
+
+ * alias.c: Cleanup comments.
+
+2012-10-15 Marc Glisse <marc.glisse@inria.fr>
+
+ PR tree-optimization/54915
+ * tree-ssa-forwprop.c (simplify_vector_constructor): Check
+ argument's type.
+
+2012-10-15 Richard Biener <rguenther@suse.de>
+
+ * data-streamer.h (bp_pack_string_with_length): New function.
+ (bp_pack_string): Likewise.
+ (bp_unpack_indexed_string): Likewise.
+ (bp_unpack_string): Likewise.
+ * data-streamer-out.c (bp_pack_string_with_length): Likewise.
+ (bp_pack_string): Likewise.
+ * data-streamer-in.c (bp_unpack_indexed_string): Likewise.
+ (bp_unpack_string): Likewise.
+ * tree-streamer-out.c (pack_ts_translation_unit_decl_value_fields):
+ Pack TRANSLATION_UNIT_LANGUAGE here, not ...
+ (write_ts_translation_unit_decl_tree_pointers): ... here. Remove.
+ (streamer_pack_tree_bitfields): Adjust.
+ (streamer_write_tree_body): Likewise.
+ * tree-streamer-in.c (unpack_ts_translation_unit_decl_value_fields):
+ Unpack TRANSLATION_UNIT_LANGUAGE here, not ...
+ (lto_input_ts_translation_unit_decl_tree_pointers): ... here. Remove.
+ (unpack_value_fields): Adjust.
+ (streamer_read_tree_body): Likewise.
+
+2012-10-15 J"orn Rennecke <joern.rennecke@arc.com>
+
+ * genoutput.c (process_template): Process '*' in '@' alternatives.
+ * doc/md.texi (node Output Statement): Provide example for the above.
+
+2012-10-15 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/54920
+ * tree-ssa-pre.c (create_expression_by_pieces): Properly
+ allocate temporary storage for all NARY elements.
+
+2012-10-15 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * web.c (union_match_dups): Properly handle OP_INOUT match_dups.
+
+2012-10-15 Eric Botcazou <ebotcazou@adacore.com>
+
+ * expr.c (expand_expr_real_1) <VIEW_CONVERT_EXPR>: Do not unnecessarily
+ copy the object in the MEM_P case.
+
+2012-10-15 Richard Guenther <rguenther@suse.de>
+
+ * tree-streamer-out.c (streamer_pack_tree_bitfields): Back
+ BINFO_BASE_ACCESSES and CONSTRUCTOR lengths here.
+ (streamer_write_chain): Write TREE_CHAIN as null-terminated list.
+ (write_ts_exp_tree_pointers): Adjust.
+ (write_ts_binfo_tree_pointers): Likewise.
+ (write_ts_constructor_tree_pointers): Likewise.
+ * tree-streamer-in.c (streamer_read_chain): Read TREE_CHAIN as
+ null-terminated list.
+ (unpack_value_fields): Unpack BINFO_BASE_ACCESSES and
+ CONSTRUCTOR lengths and materialize the arrays.
+ (lto_input_ts_exp_tree_pointers): Adjust.
+ (lto_input_ts_binfo_tree_pointers): Likewise.
+ (lto_input_ts_constructor_tree_pointers): Likewise.
+
+2012-10-14 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/mmix/mmix.c (mmix_opposite_regno): Handle the
+ return-value register too.
+
+2012-10-14 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR rtl-optimization/38711
+ * df.h (df_get_live_out, df_get_live_in): Make static inline functions.
+ * df-problems.c (df_get_live_out, df_get_live_in): Moved to df.h.
+ * ira-lives.c (process_bb_node_lives): Use df_get_live_out instead of
+ DF_LR_OUT.
+ * ira-build.c (create_bb_allocnos): Likewise.
+ (create_loop_allocnos): Likewise, and use df_get_live_in instead of
+ DF_LR_IN.
+ * ira-emit.c (generate_edge_moves): Likewise.
+ (add_ranges_and_copies): Likewise.
+ * ira-color.c (ira_loop_edge_freq): Use df_get_live_out instead of
+ DF_LR_OUT, and df_get_live_in instead of DF_LR_IN.
+ * ira.c (mark_elimination): Update DF_LR and DF_LIVE.
+ (build_insn_chain): Use df_get_live_out instead of DF_LR_OUT.
+ (do_reload): Remove the DF_LIVE problem for -O1.
+
+2012-10-14 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR rtl-optimization/54919
+ * loop-unroll.c (struct var_to_expand): Remove accum_pos field.
+ (analyze_insn_to_expand_var): Do not record accum_pos.
+ (expand_var_during_unrolling): Use validate_replace_rtx_group to
+ perform replacement of all references to SET_DEST (set) with the
+ new register, including references in REG_EQUAL notes.
+ (insert_var_expansion_initialization): Insert initializatio insns
+ at the bottom of the pre-header of the loop.
+
+2012-10-14 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa-loop-niter.c (estimate_numbers_of_iterations_loop): Do not
+ predict loops with multiple exits realistically.
+ * cfgloopanal.c (single_likely_exit): New function.
+
+2012-10-14 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.md: Remove empty predicates and/or constraints.
+ * config/alpha/sync.md: Ditto.
+
+2012-10-13 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.md (I24MODE): New mode iterator.
+ (any_divmod): New code iterator.
+ (<code>si3): Macroize expander from {div,mod,udiv,umod}si3 using
+ any_divmod code iterator.
+ (<code>si3): Macroize expander from {div,mod,udiv,umod}di3 using
+ any_divmod code iterator.
+ (extendqi<mode>2): Macroize insn from extendqi{hi,si}2 using
+ I24MODE mode iterator.
+ (unaligned_store<mode>): Macroize expander from unaligned_store{qi,hi}
+ using I12MODE mode iterator.
+ (mov<mode>): Macroize expander from mov{qi,hi} using
+ I12MODE mode iterator.
+
+2012-10-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR rtl-optimization/54871
+ * loop-iv.c (simplify_using_initial_values): When scanning previous
+ basic blocks, prune the recorded conditions if the current insn was
+ not used to make a replacement.
+
+ * loop-unroll.c (decide_unroll_constant_iterations): Clean up message.
+ (unroll_loop_constant_iterations): Clarify head comment.
+ (decide_unroll_runtime_iterations): Clean up message.
+ (unroll_loop_runtime_iterations): Clarify head comment.
+ (decide_peel_simple): Clean up message.
+ (peel_loop_simple): Clarify head comment.
+ (decide_unroll_stupid): Clean up message.
+ (unroll_loop_stupid): Clarify head comment.
+
+2012-10-13 Andreas Schwab <schwab@linux-m68k.org>
+
+ PR gcov-profile/44728
+ * gcov.c (create_file_names): When stripping extension only look
+ at base name.
+
+2012-10-13 Jan Hubicka <jh@suse.cz>
+
+ * loop-iv.c (determine_max_iter): Fix handling of AND.
+ (iv_number_of_iterations): Record upper bounds as unsigned
+ values.
+
+2012-10-13 Steven Bosscher <steven@gcc.gnu.org>
+
+ * ira.c (ira): Set current_loops to &ira_loops before recording
+ loop exits. Release recorded exits and loops early.
+
+2012-10-13 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * builtins.c (expand_builtin_set_thread_pointer): Use
+ create_input_operand() instead of create_fixed_operand().
+
+2012-10-13 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.md (FMODE): New mode iterator.
+ (modesuffix): Handle SF and DF modes.
+ (opmode): New mode attribute.
+ (abs<mode>2): Macroize insn from abs{sf,df}2 using FMODE mode iterator.
+ (*nabs<mode>2): Macroize insn from *nabs{sf,df}2 using
+ FMODE mode iterator.
+ (neg<mode>2): Macroize insn from neg{sf,df}2 using FMODE mode iterator.
+ (copysign<mode>3): Macroize insn from copysign{sf,df}3 using
+ FMODE mode iterator.
+ (*ncopysign<mode>3): Macroize insn from *ncopysign{sf,df}3 using
+ FMODE mode iterator.
+ (*add<mode>3_ieee): Macroize insn from *add{sf,df}_ieee using
+ FMODE mode iterator.
+ (add<mode>3): Macroize insn from add{sf,df}3 using FMODE mode iterator.
+ (*sub<mode>3_ieee): Macroize insn from *sub{sf,df}3_ieee using
+ FMODE mode iterator.
+ (sub<mode>3): Macroize insn from sub{sf,df}3 using FMODE mode iterator.
+ (*mul<mode>3_ieee): Macroize insn from *mul{sf,df}3_ieee using
+ FMODE mode iterator.
+ (mul<mode>3): Macroize insn from mul{sf,df}3 using FMODE mode iterator.
+ (*div<mode>3_ieee): Macroize insn from *div{sf,df}3_ieee using
+ FMODE mode iterator.
+ (div<mode>3): Macroize insn from div{sf,df}3 using FMODE mode iterator.
+ (*sqrt<mode>2_ieee): Macroize insn from *sqrt{sf,df}2_ieee using
+ FMODE mode iterator.
+ (sqrt<mode>2): Macroize insn from sqrt{sf,df}2
+ using FMODE mode iterator.
+ (*mov<mode>cc_internal): Macroize insn from *mov{sf,df}cc_internal
+ using FMODE mode iterator.
+ (mov<mode>cc): Macroize expander from mov{sf,df}cc
+ using FMODE mode iterator.
+
+2012-10-12 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54602
+ * config/sh/sh.md: Correct define_delay for return insns.
+ (*movsi_pop): Delete.
+
+2012-10-12 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54680
+ * config/sh/sh.c (sh_fsca_sf2int, sh_fsca_int2sf): Fix swapped
+ comments.
+ * config/sh/predicates.md (fpul_operand): Add comment.
+ (fpul_fsca_operand, fsca_scale_factor): New predicates.
+ * config/sh/sh.md (fsca): Move below sincossf3 expander. Convert to
+ insn_and_split. Use fpul_fsca_operand and fsca_scale_factor
+ predicates. Simplify fpul operand in splitter.
+
+2012-10-12 Jan Hubicka <jh@suse.cz>
+
+ * tree-ssa-threadupdate.c (def_split_header_continue_p): Do not
+ escape the loop.
+
+2012-10-12 Jan Hubicka <jh@suse.cz>
+
+ * web.c (web_main): Do not set DF_RD_PRUNE_DEAD_DEFS flag.
+
+2012-10-12 Aaron Gray <aaronngray.lists@gmail.com>
+ Diego Novillo <dnovillo@google.com>
+
+ * gengtype-lex.l: Support for C++ single line comments.
+ Support for classes.
+ (CXX_KEYWORD): New. Support C++ keywords inline, public,
+ protected, private, template, operator, friend, &, ~.
+ (TYPEDEF): New. Support typedef.
+ * gengtype-parser.c: updated 'token_names[]'
+ (direct_declarator): Add support for parsing functions and ctors.
+
+2012-10-12 Diego Novillo <dnovillo@google.com>
+
+ * doc/gty.texi: Document C++ limitations in gengtype.
+ * gengtype-lex.l (CID): Rename from ID.
+ (ID): Include scoping '::' as part of the identifier name.
+ * gengtype-parse.c (token_names): Update.
+ (token_value_format): Update.
+ (consume_until_eos): Rename from consume_until_semi.
+ Remove unused argument IMMEDIATE. Update all callers.
+ Also consider '}' as a finalizer.
+ (consume_until_comma_or_eos): Rename from
+ consume_until_comma_or_semi.
+ Remove unused argument IMMEDIATE. Update all callers.
+ Also consider '}' as a finalizer.
+ (direct_declarator): Add documentation on ctor support.
+ Add argument IN_STRUCT.
+ If the token following ID is a '(', consider ID a
+ function and return NULL.
+ If the token following '(' is not a '*', and IN_STRUCT is true,
+ conclude that this is a ctor and return NULL.
+ If the token is IGNORABLE_CXX_KEYWORD, return NULL.
+ (inner_declarator): Add argument IN_STRUCT.
+ Update all callers.
+ (declarator): Add argument IN_STRUCT with default value false.
+ Update all callers.
+ (type): Document argument NESTED.
+ Skip over C++ inheritance specifiers.
+ If a token TYPEDEF is found, emit an error.
+ If an enum is found inside a class/structure, emit an error.
+ (typedefs, structures, param_structs, variables): Initialize.
+ (new_structure): Do not complain about duplicate
+ structures if S has a line location set.
+ * gengtype-state.c (write_state_type): Remove default handler.
+ Add handler for TYPE_NONE.
+ (read_state_scalar_char_type):
+ * gengtype.c: Fix spacing.
+ * gengtype.h (enum gty_token): Add name. Add token
+ IGNORABLE_CXX_KEYWORD.
+
+2012-10-12 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * config/arm/arm.md (get_thread_pointersi): Moved to place with
+ other TLS related patterns.
+
+2012-10-12 Richard Biener <rguenther@suse.de>
+
+ * tree-streamer-out.c (pack_ts_target_option): Rename from ...
+ (write_ts_target_option): ... this.
+ (pack_ts_optimization): Rename from ...
+ (write_ts_optimization): ... this.
+ (streamer_pack_tree_bitfields): Pack them in the bitfield section ...
+ (streamer_write_tree_body): ... not here.
+ * tree-streamer-in.c (unpack_ts_target_option): Rename from ...
+ (lto_input_ts_target_option): ... this.
+ (unpack_ts_optimization): Rename from ...
+ (lto_input_ts_optimization): ... this.
+ (unpack_value_fields): Unpack them from the bitfield section ...
+ (streamer_read_tree_body): ... not from here.
+
+2012-10-12 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.md (vecmodesuffix): New mode attribute.
+ (modesuffix): Handle V8QI and V4HI modes.
+ (any_maxmin): New code iterator.
+ (maxmin): New code attribute.
+ (<code><mode>3): Macroize insn from {smax,smin,umax,umin}{qi,hi}3
+ using any_maxmin code iterator and I12MODE mode iterator.
+ (<code><mode>3): Macroize insn from {smax,smin,umax,umin}{v8qi,v4hi}3
+ using any_maxmin code iterator and VEC12 mode iterator.
+
+2012-10-12 Marc Glisse <marc.glisse@inria.fr>
+
+ * optabs.c (vector_compare_rtx): Change prototype.
+ (expand_vec_cond_expr): Handle VEC_COND_EXPR whose first operand
+ is not a comparison.
+ * gimplify.c (gimplify_expr): Handle VEC_COND_EXPR.
+
+2012-10-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/54894
+ * tree-vect-stmts.c (get_vectype_for_scalar_type_and_size):
+ Handle over-aligned scalar types properly.
+
+2012-10-12 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54760
+ * config/sh/sh.c (bdesc): Remove thread pointer built-ins.
+ * config/sh/sh.md (get_thread_pointer, set_thread_pointer): Append mode
+ name 'si'.
+
+2012-10-12 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/51244
+ * config/sh/sh.md (negsi_cond, negdi_cond, stack_protect_test): Remove
+ get_t_reg_rtx when invoking gen_branch_true or gen_branch_false.
+ (*zero_extend<mode>si2_compact): Convert to insn_and_split. Convert
+ zero extensions of T bit stores to reg moves in splitter. Remove
+ obsolete unnamed peephole2 that caught zero extensions after negc T bit
+ stores.
+ (*branch_true_eq, *branch_false_ne): Delete.
+ (branch_true, branch_false): Convert insn to expander. Move actual
+ insn logic to...
+ (*cbranch_t): ...this new insn_and_split. Try to find preceding
+ redundant T bit stores and tests and combine them with the conditional
+ branch if possible in the splitter.
+ (movrt_xor, *movt_movrt): New insn_and_split.
+ * config/sh/predicates.md (cbranch_treg_value): New predicate.
+ * config/sh/sh-protos.h (sh_eval_treg_value): Forward declare...
+ * config/sh/sh.c (sh_eval_treg_value): ...this new function.
+ (expand_cbranchsi4, expand_cbranchdi4): Remove get_t_reg_rtx
+ when invoking gen_branch_true or gen_branch_false.
+
+2012-10-11 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.md (IMODE): New mode iterator.
+ (I124MODE): Ditto.
+ (I248MODE): Ditto.
+ (modesuffix): Handle QI and HI modes.
+ (zero_extendqi<mode>2): Macroize insn from zero_extendqi{hi,si,di}2
+ using I248MODE mode iterator.
+ (zero_extendhi<mode>2): Macroize insn from zero_extendhi{si,di}2
+ using I48MODE mode iterator.
+ (andnot<mode>3): Macroize insn from andnot{si,di}3 using
+ I48MODE mode iterator.
+ (ins<modesuffix>l_const): Macroize insn from ins{b,w,l}l_const
+ using I248MODE mode iterator.
+ (ins<modesuffix>l): Macroize insn from ins{b,w,l}l
+ using I248MODE mode iterator.
+ (*mov<mode>cc_internal): Macroize insn from
+ *mov{qi,hi,si,di}cc_internal using IMODE mode iterator.
+ (*mov<mode>cc_lbc): Macroize insn from
+ *mov{qi,hi,si,di}cc_lbc using IMODE mode iterator.
+ (*mov<mode>cc_lbs): Macroize insn from
+ *mov{qi,hi,si,di}cc_lbs using IMODE mode iterator.
+ (mov<mode>cc): Macroize expander from mov{si,di}cc
+ using I48MODE mode iterator.
+
+2012-10-11 Steven Bosscher <steven@gcc.gnu.org>
+
+ * ira-build.c (ira_loop_tree_body_rev_postorder): New function.
+ (ira_traverse_loop_tree): Traverse a loop's basic blocks in
+ reverse post-order of the reversed control-flow direction.
+ * ira-conflicts.c (ira_build_conflicts): Pass add_copies as
+ the pre-order function to ira_traverse_loop_tree to preserve
+ the existing semantics.
+
+ * ira-lives.c (remove_some_program_points_and_update_live_ranges):
+ Squeeze out live range chain elements if their program points are
+ connected.
+
+2012-10-11 Jakub Jelinek <jakub@redhat.com>
+
+ * tree.def (REDUC_PLUS_EXPR): Fix up comment.
+
+ * fold-const.c (fold_unary_loc): Handle REDUC_MIN_EXPR,
+ REDUC_MAX_EXPR and REDUC_PLUS_EXPR.
+
+2012-10-11 James Lemke <jwlemke@codesourcery.com>
+
+ * config/rs6000/predicates.md (zero_fp_constant): Fix comment.
+ * config/rs6000/rs6000.md (return_pred): Fix null return.
+ * config/rs6000/rs6000.c (rs6000_emit_set_const): Fix indentation.
+ (print_operand): Make FALLTHRU obvious.
+ (output_cbranch): Correct comment.
+
+2012-10-11 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.md (DWI): New mode attribute.
+ (*sadd<modesuffix>): Macroize insn from *saddl and *saddq using
+ I48MODE mode iterator.
+ (addv<mode>3): Macroize insn from addvsi3 and addvdi3 using
+ I48MODE mode iterator.
+ (neg<mode>2): Macroize insn from negsi2 and negdi2 using
+ I48MODE mode iterator.
+ (negv<mode>2): Macroize insn from negvsi2 and negvdi2 using
+ I48MODE mode iterator.
+ (sub<mode>3): Macroize insn from subsi3 and subdi3 using
+ I48MODE mode iterator.
+ (*ssub<modesuffix>): Macroize insn from *ssubl and *ssubq using
+ I48MODE mode iterator.
+ (subv<mode>3): Macroize insn from subvsi3 and subvdi3 using
+ I48MODE mode iterator.
+ (mul<mode>3): Macroize insn from mulsi3 and muldi3 using
+ I48MODE mode iterator.
+ (mulv<mode>3): Macroize insn from mulvsi3 and mulvdi3 using
+ I48MODE mode iterator.
+ (*iornot<mode>3): Macroize insn from *iornotsi3 and *iornotdi3 using
+ I48MODE mode iterator.
+ (*xornot<mode>3): Macroize insn from *xornotsi3 and *xornotdi3 using
+ I48MODE mode iterator.
+
+2012-10-11 Jason Merrill <jason@redhat.com>
+
+ * configure.ac (gcc_cv_as_aix_ref): Fix typo.
+ * configure: Regenerate.
+
+2012-10-11 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * builtins.c (expand_builtin_thread_pointer): New.
+ (expand_builtin_set_thread_pointer): New.
+ (expand_builtin): Add BUILT_IN_THREAD_POINTER,
+ BUILT_IN_SET_THREAD_POINTER expand cases.
+ * builtins.def (BUILT_IN_THREAD_POINTER):
+ New __builtin_thread_pointer builtin.
+ (BUILT_IN_SET_THREAD_POINTER):
+ New __builtin_set_thread_pointer builtin.
+ * optabs.def (get_thread_pointer,set_thread_pointer):
+ New standard names.
+ * doc/md.texi (Standard Names): Document get_thread_pointer and
+ set_thread_pointer patterns.
+ * config/alpha/alpha.md (get_thread_pointerdi): Rename from load_tp.
+ (set_thread_pointerdi): Rename from set_tp.
+ * config/alpha/alpha.c (alpha_legitimize_address_1): Change
+ gen_load_tp calls to gen_get_thread_pointerdi.
+ (alpha_builtin): Remove ALPHA_BUILTIN_THREAD_POINTER,
+ ALPHA_BUILTIN_SET_THREAD_POINTER.
+ (code_for_builtin): Remove CODE_FOR_load_tp, CODE_FOR_set_tp.
+ (alpha_init_builtins): Remove __builtin_thread_pointer,
+ __builtin_set_thread_pointer machine-specific builtins.
+ (alpha_expand_builtin_thread_pointer): Add hook function for
+ TARGET_EXPAND_BUILTIN_THREAD_POINTER.
+ (alpha_expand_builtin_set_thread_pointer): Add hook function for
+ TARGET_EXPAND_BUILTIN_SET_THREAD_POINTER.
+ (alpha_fold_builtin): Remove ALPHA_BUILTIN_THREAD_POINTER,
+ ALPHA_BUILTIN_SET_THREAD_POINTER cases.
+ * config/arm/arm.md (get_thread_pointersi): New pattern.
+ * config/arm/arm-protos.h (arm_load_tp): Add extern declaration.
+ * config/arm/arm.c (arm_load_tp): Remove static.
+ (arm_builtins): Remove ARM_BUILTIN_THREAD_POINTER.
+ (arm_init_tls_builtins): Remove function.
+ (arm_init_builtins): Remove call to arm_init_tls_builtins().
+ (arm_expand_builtin): Remove ARM_BUILTIN_THREAD_POINTER case.
+ * config/mips/mips.md (get_thread_pointer<mode>): New pattern.
+ * config/mips/mips-protos.h (mips_expand_thread_pointer):
+ Add extern declaration.
+ * config/mips/mips.c (mips_expand_thread_pointer):
+ Renamed from mips_get_tp.
+ (mips_get_tp): New stub calling mips_expand_thread_pointer.
+ * config/s390/s390.c (s390_builtin,code_for_builtin_64,
+ code_for_builtin_31,s390_init_builtins,s390_expand_builtin): Remove.
+ * config/s390/s390.md (get_tp_64,get_tp_31,set_tp_64,set_tp_31):
+ Remove.
+ (get_thread_pointer<mode>,set_thread_pointer<mode>):
+ New, adapted from removed patterns.
+ * config/xtensa/xtensa.md (get_thread_pointersi):
+ Renamed from load_tp.
+ (set_thread_pointersi): Renamed from set_tp.
+ * config/xtensa/xtensa.c (xtensa_legitimize_tls_address):
+ Change gen_load_tp calls to gen_get_thread_pointersi.
+ (xtensa_builtin): Remove XTENSA_BUILTIN_THREAD_POINTER and
+ XTENSA_BUILTIN_SET_THREAD_POINTER.
+ (xtensa_init_builtins): Remove __builtin_thread_pointer,
+ __builtin_set_thread_pointer machine-specific builtins.
+ (xtensa_fold_builtin): Remove XTENSA_BUILTIN_THREAD_POINTER,
+ XTENSA_BUILTIN_SET_THREAD_POINTER cases.
+ (xtensa_expand_builtin): Remove XTENSA_BUILTIN_THREAD_POINTER,
+ XTENSA_BUILTIN_SET_THREAD_POINTER cases.
+
+2012-10-11 Marc Glisse <marc.glisse@inria.fr>
+
+ * doc/extend.texi (Vector Extensions): C++ improvements.
+ * doc/generic.texi (LSHIFT_EXPR, RSHIFT_EXPR): Mixed vector-scalar.
+ (LT_EXPR, LE_EXPR, GT_EXPR, GE_EXPR, EQ_EXPR, NE_EXPR): Specify
+ the vector case.
+ (VEC_COND_EXPR): Document it.
+
+2012-10-11 Terry Guo <terry.guo@arm.com>
+
+ * config/arm/arm.c (arm_arch6m): New variable to denote armv6-m
+ architecture.
+ * config/arm/arm.h (TARGET_HAVE_DMB): The armv6-m also has DMB
+ instruction.
+
+2012-10-11 Hans-Peter Nilsson <hp@bitrange.com>
+
+ PR target/54373
+ * configure.ac (out-of-tree linker .hidden support) Set to "no"
+ for mmix-knuth-mmixware.
+ * configure: Regenerate.
+
+ * configure.ac (gcc_cv_as_comdat_group_group): Default to no.
+ * configure: Regenerate.
+
+ * acinclude.m4 (_gcc_COMPUTE_GAS_VERSION): Allow a single
+ character to quote the VERSION= contents. Sanity-check contents.
+ * configure.ac ("what linker to use" ld version extraction): Ditto.
+ * configure: Regenerate.
+
+2012-10-10 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/rs6000.h (PRINT_OPERAND_PUNCT_VALID_P): Delete '.'.
+
+2012-10-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/54877
+ * tree-vect-loop.c (vect_is_simple_reduction_1): For MINUS_EXPR
+ use make_ssa_name instead of copy_ssa_name.
+
+2012-10-10 Richard Biener <rguenther@suse.de>
+
+ * lto-streamer-in.c (lto_input_location_bitpack): Rename to ...
+ (lto_input_location): ... this. Kill original.
+ (input_eh_region): Adjust.
+ (input_struct_function_base): Likewise.
+ (lto_read_tree): Likewise.
+ * lto-streamer-out.c (lto_output_location_bitpack): Rename to ...
+ (lto_output_location): ... this. Kill original.
+ (lto_write_tree): Adjust.
+ (output_eh_region): Likewise.
+ (output_struct_function_base): Likewise.
+ * lto-streamer.c (lto_streamer_hooks_init): Initialize location hooks.
+ * lto-streamer.h (lto_input_location): Adjust prototype.
+ (lto_output_location): Likewise.
+ * streamer-hooks.h (struct streamer_hooks): Adjust prototype
+ of input_location and output_location hooks.
+ (stream_input_location): New define.
+ (stream_output_location): Likewise.
+ * tree-streamer-in.c (unpack_ts_block_value_fields): Adjust.
+ (unpack_value_fields): Likewise.
+ (streamer_read_tree_bitfields): Likewise.
+ (lto_input_ts_decl_minimal_tree_pointers): Likewise.
+ (lto_input_ts_exp_tree_pointers): Likewise.
+ (lto_input_ts_block_tree_pointers): Likewise.
+ * tree-streamer-out.c (pack_ts_block_value_fields): Adjust.
+ (streamer_pack_tree_bitfields): Likewise.
+ (write_ts_decl_minimal_tree_pointers): Likewise.
+ (write_ts_exp_tree_pointers): Likewise.
+ (write_ts_block_tree_pointers): Likewise.
+ * gimple-streamer-in.c (input_phi): Adjust.
+ (input_gimple_stmt): Likewise.
+ * gimple-streamer-out.c (output_phi): Adjust.
+ (output_gimple_stmt): Likewise.
+ * tree-streamer.h (streamer_read_tree_bitfields): Adjust prototype.
+ (streamer_pack_tree_bitfields): Likewise.
+
+2012-10-10 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000.c (altivec_expand_dst_builtin): Fix signed
+ vs. unsigned warnings by using enum type for function code.
+ (paired_expand_builtin): Likewise.
+ (spe_expand_builtin): Likewise.
+
+ * config/rs6000/rs6000-c.c (rs6000_target_modify_macros): Change
+ builtin mask, target flags masks type to HOST_WIDE_INT in
+ preparation for growing the number of ISA switches from 31 to 63.
+
+ * config/rs6000/rs6000.opt (rs6000_builtin_mask): Make mask type
+ HOST_WIDE_INT.
+
+ * config/rs6000/rs6000.c (struct builtin_description): Make
+ builtin mask field HOST_WIDE_INT. Make target flags field
+ HOST_WIDE_INT in preparation for growing the # of ISA switches.
+ (struct rs6000_builtin_info_type): Likewise.
+ (struct rs6000_ptt): Likewise.
+ (rs6000_builtin_mask_calculate): Likewise.
+ (rs6000_invalid_builtin): Likewise.
+ (rs6000_builtin_decl): Likewise.
+ (rs6000_common_init_builtins): Likewise.
+ (rs6000_darwin_file_start): Likewise.
+ (rs6000_final_prescan_insn): Likewise.
+ (rs6000_inner_target_options): Likewise.
+ (build_target_option_node): Likewise.
+ (rs6000_function_specific_print): Likewise.
+ (DEBUG_FMT_W): New format for printing HOST_WIDE_INT in hex.
+
+ * config/rs6000/rs6000-protos.h (rs6000_builtin_mask_calculate):
+ Make target flags, builtin masks arguments/return values
+ HOST_WIDE_INT in preparation for growing the number of ISA from 31
+ to 63.
+ (rs6000_target_modify_macros): Likewise.
+ (rs6000_target_modify_macros_ptr): Likewise.
+
+ * config/rs6000/rs6000.c (DEBUG_FMT_ID): Move "-32s" to a separate
+ define and change DEBUG_FMT_<x> to use it.
+ (DEBUG_FMT_D): Likewise.
+ (DEBUG_FMT_S): Likewise.
+ (DEBUG_FMT_X): Delete, no longer used.
+ (DEBUG_FMT_W): Likewise.
+ (DEBUG_FMT_WX): New debug format for printing options in a
+ friendly fashion.
+ (rs6000_debug_reg_global): If -mdebug=reg, print all of the
+ options in target_flags and target_flags_explicit. Print the
+ default options for -mcpu=<xxx>, -mtune=<xxx>, and the default
+ options. Adjust printing out the builtin options.
+ (rs6000_option_override_internal): Change printing the builtin
+ options to use rs6000_print_builtin_options.
+ (rs6000_function_specific_print): Change to use
+ rs6000_print_isa_options to print ISA flags.
+ (rs6000_print_options_internal): New function for expanded
+ -mdebug=reg option printing to print both the ISA options, and the
+ builtins that are enabled.
+ (rs6000_print_isa_options): New function to print the ISA options.
+ (rs6000_print_builtin_options): New function to print the builtin
+ functions enabled.
+
+2012-10-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/51109
+ * config/i386/bdver1.md (bdver1-mult): Remove.
+
+ PR middle-end/54879
+ * combine.c (count_rtxs): Use RTX_BIN_ARITH resp. RTX_COMM_ARITH
+ instead of '2' resp. 'c' for GET_RTX_CLASS comparisons.
+
+ PR middle-end/54862
+ * simplify-rtx.c (simplify_truncation): Compare UINTVAL instead of
+ INTVAL of second argument with precision resp. op_precision.
+
+2012-10-10 Dodji Seketeli <dodji@redhat.com>
+
+ PR middle-end/54860 - Make sure attributes hash table is created
+ * attribs.c (register_scoped_attributes): Ensure the attribute
+ hash table is created.
+
+2012-10-10 Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com>
+
+ PR target/51109
+ * config/i386/bdver1.md (bdver1_int): Automaton has been
+ split to reduce state transitions.
+
+2012-10-10 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/54876
+ * ipa-prop.c (prune_expression_for_jf_1): New function.
+ (prune_expression_for_jf): Clear EXPR_LOCATION for all
+ sub-expressions as well.
+
2012-10-10 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* config.gcc: Enable zEC12 for with-arch and with-tune
- configure switches.
+ configure switches.
* common/config/s390/s390-common.c (processor_flags_table): Add
zEC12 entry.
* config/s390/2827.md: New file.
@@ -14,8 +677,7 @@
Set parameter defaults for zEC12.
(legitimate_reload_fp_constant_p): Adjust comment.
(preferred_la_operand_p): Adjust comment.
- (s390_expand_insv): Generate insv pattern without CC clobber for
- zEC12.
+ (s390_expand_insv): Generate insv pattern without CC clobber for zEC12.
(s390_adjust_priority): Add zEC12 check.
(s390_issue_rate): Return 2 for zEC12.
(s390_reorg): Enable code optimizations for zEC12.
@@ -43,8 +705,10 @@
(*movsf_insn): Likewise.
(*movdf_insn_sp64): Likewise.
(*mov<VM32:mode>_insn): Likewise, use 'fsrc2s' instead of 'fsrc1s'.
- (*mov<VM64:mode>_insn_sp64): Likewise, use 'fsrc2s' instead of 'fsrc1s'.
- (*mov<VM64:mode>_insn_sp32): Likewise, use 'fsrc2s' instead of 'fsrc1s'.
+ (*mov<VM64:mode>_insn_sp64): Likewise, use 'fsrc2s'
+ instead of 'fsrc1s'.
+ (*mov<VM64:mode>_insn_sp32): Likewise, use 'fsrc2s'
+ instead of 'fsrc1s'.
(VIS logical instructions): Mark as visl.
(pdist_vis): Use 'pdist'.
(pditsn<mode>_vis): Use 'pdistn'.
@@ -75,15 +739,16 @@
* Makefile.in (fold-const.o): Add depencence on hash-table.h.
(dse.o): Likewise.
(cfg.o): Likewise.
- * fold-const.c (fold_checksum_tree): Change to new type-safe hash table.
+ * fold-const.c (fold_checksum_tree): Change to new
+ type-safe hash table.
* (print_fold_checksum): Likewise.
* cfg.c (var bb_original): Likewise.
* (var bb_copy): Likewise.
* (var loop_copy): Likewise.
* hash-table.h (template hash_table): Constify parameters for find...
and remove_elt... member functions.
- (hash_table::empty) Correct size expression.
- (hash_table::clear_slot) Correct deleted entry assignment.
+ (hash_table::empty) Correct size expression.
+ (hash_table::clear_slot) Correct deleted entry assignment.
* dse.c (var rtx_group_table): Change to new type-safe hash table.
2012-10-09 Steven Bosscher <steven@gcc.gnu.org>
@@ -18470,7 +19135,7 @@
2012-04-26 Bernd Schmidt <bernds@codesourcery.com>
- * PR middle-end/52997
+ PR middle-end/52997
* ira.c (find_moveable_pseudos): Call resize_reg_info.
PR middle-end/52940
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index d89fa2927fe..bc72ebf083a 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20121010
+20121015
diff --git a/gcc/acinclude.m4 b/gcc/acinclude.m4
index c24464b5977..fe7c5b699d0 100644
--- a/gcc/acinclude.m4
+++ b/gcc/acinclude.m4
@@ -393,11 +393,15 @@ for f in $gcc_cv_as_bfd_srcdir/configure \
$gcc_cv_as_gas_srcdir/configure \
$gcc_cv_as_gas_srcdir/configure.in \
$gcc_cv_as_gas_srcdir/Makefile.in ; do
- gcc_cv_gas_version=`sed -n -e 's/^[[ ]]*\(VERSION=[[0-9]]*\.[[0-9]]*.*\)/\1/p' < $f`
+ gcc_cv_gas_version=`sed -n -e 's/^[[ ]]*VERSION=[[^0-9A-Za-z_]]*\([[0-9]]*\.[[0-9]]*.*\)/VERSION=\1/p' < $f`
if test x$gcc_cv_gas_version != x; then
break
fi
done
+case $gcc_cv_gas_version in
+ VERSION=[[0-9]]*) ;;
+ *) AC_MSG_ERROR([[cannot find version of in-tree assembler]]);;
+esac
gcc_cv_gas_major_version=`expr "$gcc_cv_gas_version" : "VERSION=\([[0-9]]*\)"`
gcc_cv_gas_minor_version=`expr "$gcc_cv_gas_version" : "VERSION=[[0-9]]*\.\([[0-9]]*\)"`
gcc_cv_gas_patch_version=`expr "$gcc_cv_gas_version" : "VERSION=[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)"`
diff --git a/gcc/alias.c b/gcc/alias.c
index 0c6a7442b84..09aef1137ef 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -60,14 +60,13 @@ along with GCC; see the file COPYING3. If not see
struct Z z2, *pz;
- py = &px1.y1;
+ py = &x1.y1;
px2 = &x1;
Consider the four questions:
Can a store to x1 interfere with px2->y1?
Can a store to x1 interfere with px2->z2?
- (*px2).z2
Can a store to x1 change the value pointed to by with py?
Can a store to x1 change the value pointed to by with pz?
@@ -78,24 +77,24 @@ along with GCC; see the file COPYING3. If not see
a store through a pointer to an X can overwrite any field that is
contained (recursively) in an X (unless we know that px1 != px2).
- The last two of the questions can be solved in the same way as the
- first two questions but this is too conservative. The observation
- is that in some cases analysis we can know if which (if any) fields
- are addressed and if those addresses are used in bad ways. This
- analysis may be language specific. In C, arbitrary operations may
- be applied to pointers. However, there is some indication that
- this may be too conservative for some C++ types.
+ The last two questions can be solved in the same way as the first
+ two questions but this is too conservative. The observation is
+ that in some cases we can know which (if any) fields are addressed
+ and if those addresses are used in bad ways. This analysis may be
+ language specific. In C, arbitrary operations may be applied to
+ pointers. However, there is some indication that this may be too
+ conservative for some C++ types.
The pass ipa-type-escape does this analysis for the types whose
instances do not escape across the compilation boundary.
Historically in GCC, these two problems were combined and a single
- data structure was used to represent the solution to these
+ data structure that was used to represent the solution to these
problems. We now have two similar but different data structures,
- The data structure to solve the last two question is similar to the
- first, but does not contain have the fields in it whose address are
- never taken. For types that do escape the compilation unit, the
- data structures will have identical information.
+ The data structure to solve the last two questions is similar to
+ the first, but does not contain the fields whose address are never
+ taken. For types that do escape the compilation unit, the data
+ structures will have identical information.
*/
/* The alias sets assigned to MEMs assist the back-end in determining
diff --git a/gcc/attribs.c b/gcc/attribs.c
index b330f27d89d..d167c1f6e13 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -146,7 +146,8 @@ register_scoped_attributes (const struct attribute_spec * attributes,
memset (&sa, 0, sizeof (sa));
sa.ns = ns;
sa.attributes = VEC_alloc (attribute_spec, heap, 64);
- result = VEC_safe_push (scoped_attributes, heap, attributes_table, sa);
+ result = VEC_safe_push (scoped_attributes, heap, attributes_table, sa);
+ result->attribute_hash = htab_create (200, hash_attr, eq_attr, NULL);
}
/* Really add the attributes to their namespace now. */
@@ -284,8 +285,7 @@ register_scoped_attribute (const struct attribute_spec *attr,
gcc_assert (attr != NULL && name_space != NULL);
- if (name_space->attribute_hash == NULL)
- name_space->attribute_hash = htab_create (200, hash_attr, eq_attr, NULL);
+ gcc_assert (name_space->attribute_hash != NULL);
str.str = attr->name;
str.length = strlen (str.str);
diff --git a/gcc/builtins.c b/gcc/builtins.c
index e6b10ea43b9..c309566919e 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5744,6 +5744,45 @@ expand_builtin_sync_synchronize (void)
expand_mem_thread_fence (MEMMODEL_SEQ_CST);
}
+static rtx
+expand_builtin_thread_pointer (tree exp, rtx target)
+{
+ enum insn_code icode;
+ if (!validate_arglist (exp, VOID_TYPE))
+ return const0_rtx;
+ icode = direct_optab_handler (get_thread_pointer_optab, Pmode);
+ if (icode != CODE_FOR_nothing)
+ {
+ struct expand_operand op;
+ if (!REG_P (target) || GET_MODE (target) != Pmode)
+ target = gen_reg_rtx (Pmode);
+ create_output_operand (&op, target, Pmode);
+ expand_insn (icode, 1, &op);
+ return target;
+ }
+ error ("__builtin_thread_pointer is not supported on this target");
+ return const0_rtx;
+}
+
+static void
+expand_builtin_set_thread_pointer (tree exp)
+{
+ enum insn_code icode;
+ if (!validate_arglist (exp, POINTER_TYPE, VOID_TYPE))
+ return;
+ icode = direct_optab_handler (set_thread_pointer_optab, Pmode);
+ if (icode != CODE_FOR_nothing)
+ {
+ struct expand_operand op;
+ rtx val = expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX,
+ Pmode, EXPAND_NORMAL);
+ create_input_operand (&op, val, Pmode);
+ expand_insn (icode, 1, &op);
+ return;
+ }
+ error ("__builtin_set_thread_pointer is not supported on this target");
+}
+
/* Expand an expression EXP that calls a built-in function,
with result going to TARGET if that's convenient
@@ -6809,6 +6848,13 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
maybe_emit_free_warning (exp);
break;
+ case BUILT_IN_THREAD_POINTER:
+ return expand_builtin_thread_pointer (exp, target);
+
+ case BUILT_IN_SET_THREAD_POINTER:
+ expand_builtin_set_thread_pointer (exp);
+ return const0_rtx;
+
default: /* just do library call, if unknown builtin */
break;
}
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 69000bcfc04..177bf4963aa 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -782,6 +782,17 @@ DEF_BUILTIN (BUILT_IN_PROFILE_FUNC_ENTER, "__cyg_profile_func_enter", BUILT_IN_N
DEF_BUILTIN (BUILT_IN_PROFILE_FUNC_EXIT, "__cyg_profile_func_exit", BUILT_IN_NORMAL, BT_FN_VOID_PTR_PTR, BT_LAST,
false, false, false, ATTR_NULL, true, true)
+/* TLS thread pointer related builtins. */
+DEF_BUILTIN (BUILT_IN_THREAD_POINTER, "__builtin_thread_pointer",
+ BUILT_IN_NORMAL, BT_FN_PTR, BT_LAST,
+ false, false, true, ATTR_CONST_NOTHROW_LIST, true,
+ targetm.have_tls)
+
+DEF_BUILTIN (BUILT_IN_SET_THREAD_POINTER, "__builtin_set_thread_pointer",
+ BUILT_IN_NORMAL, BT_FN_VOID_PTR, BT_LAST,
+ false, false, true, ATTR_NOTHROW_LIST, true,
+ targetm.have_tls)
+
/* TLS emulation. */
DEF_BUILTIN (BUILT_IN_EMUTLS_GET_ADDRESS, targetm.emutls.get_address,
BUILT_IN_NORMAL,
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 470d1b63b4b..bb82be4d72d 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,29 @@
+2012-10-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/54381
+ * c-common.h (sizeof_pointer_memaccess_warning): Adjust prototype.
+ * c-common.c (sizeof_pointer_memaccess_warning): Take array of 3
+ locs and array of 3 trees instead of just single loc and single
+ sizeof_arg tree. Handle __builtin___*_chk builtins too, and
+ also stpncpy, bcopy, bcmp, bzero, snprintf and vsnprintf builtins.
+ For *cmp* builtins that take two sources strings report warnings
+ about first and second source, not about destination and source.
+
+2012-10-12 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/53055
+ * c-common.h (enum ref_operator) [RO_ARROW_STAR]: New.
+
+2012-10-11 Eric Botcazou <ebotcazou@adacore.com>
+
+ * c-ada-spec.c (dump_ada_template): Bail out for template declarations
+ declaring something coming from another file.
+
+2012-10-10 Arnaud Charlet <charlet@adacore.com>
+
+ PR ada/54845
+ * c-ada-spec.c (print_ada_struct_decl): Increase buf size.
+
2012-10-09 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/54194
diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c
index 4f38a63ad89..631ee7a5843 100644
--- a/gcc/c-family/c-ada-spec.c
+++ b/gcc/c-family/c-ada-spec.c
@@ -1700,10 +1700,18 @@ static int
dump_ada_template (pretty_printer *buffer, tree t,
int (*cpp_check)(tree, cpp_operation), int spc)
{
- tree inst = DECL_VINDEX (t);
/* DECL_VINDEX is DECL_TEMPLATE_INSTANTIATIONS in this context. */
+ tree inst = DECL_VINDEX (t);
+ /* DECL_RESULT_FLD is DECL_TEMPLATE_RESULT in this context. */
+ tree result = DECL_RESULT_FLD (t);
int num_inst = 0;
+ /* Don't look at template declarations declaring something coming from
+ another file. This can occur for template friend declarations. */
+ if (LOCATION_FILE (decl_sloc (result, false))
+ != LOCATION_FILE (decl_sloc (t, false)))
+ return 0;
+
while (inst && inst != error_mark_node)
{
tree types = TREE_PURPOSE (inst);
@@ -3068,7 +3076,7 @@ print_ada_struct_decl (pretty_printer *buffer, tree node, tree type,
tree tmp;
int is_union =
TREE_CODE (node) == UNION_TYPE || TREE_CODE (node) == QUAL_UNION_TYPE;
- char buf[16];
+ char buf[32];
int field_num = 0;
int field_spc = spc + INDENT_INCR;
int need_semicolon;
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index b9186489a40..34cfb98f85b 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -1847,52 +1847,105 @@ strict_aliasing_warning (tree otype, tree type, tree expr)
sizeof as last operand of certain builtins. */
void
-sizeof_pointer_memaccess_warning (location_t loc, tree callee,
- VEC(tree, gc) *params, tree sizeof_arg,
+sizeof_pointer_memaccess_warning (location_t *sizeof_arg_loc, tree callee,
+ VEC(tree, gc) *params, tree *sizeof_arg,
bool (*comp_types) (tree, tree))
{
tree type, dest = NULL_TREE, src = NULL_TREE, tem;
- bool strop = false;
+ bool strop = false, cmp = false;
+ unsigned int idx = ~0;
+ location_t loc;
if (TREE_CODE (callee) != FUNCTION_DECL
|| DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL
- || sizeof_arg == error_mark_node
|| VEC_length (tree, params) <= 1)
return;
- type = TYPE_P (sizeof_arg) ? sizeof_arg : TREE_TYPE (sizeof_arg);
- if (!POINTER_TYPE_P (type))
- return;
-
switch (DECL_FUNCTION_CODE (callee))
{
case BUILT_IN_STRNCMP:
case BUILT_IN_STRNCASECMP:
+ cmp = true;
+ /* FALLTHRU */
case BUILT_IN_STRNCPY:
+ case BUILT_IN_STRNCPY_CHK:
case BUILT_IN_STRNCAT:
+ case BUILT_IN_STRNCAT_CHK:
+ case BUILT_IN_STPNCPY:
+ case BUILT_IN_STPNCPY_CHK:
strop = true;
/* FALLTHRU */
case BUILT_IN_MEMCPY:
+ case BUILT_IN_MEMCPY_CHK:
case BUILT_IN_MEMMOVE:
+ case BUILT_IN_MEMMOVE_CHK:
+ if (VEC_length (tree, params) < 3)
+ return;
+ src = VEC_index (tree, params, 1);
+ dest = VEC_index (tree, params, 0);
+ idx = 2;
+ break;
+ case BUILT_IN_BCOPY:
+ if (VEC_length (tree, params) < 3)
+ return;
+ src = VEC_index (tree, params, 0);
+ dest = VEC_index (tree, params, 1);
+ idx = 2;
+ break;
case BUILT_IN_MEMCMP:
+ case BUILT_IN_BCMP:
if (VEC_length (tree, params) < 3)
return;
src = VEC_index (tree, params, 1);
dest = VEC_index (tree, params, 0);
+ idx = 2;
+ cmp = true;
break;
case BUILT_IN_MEMSET:
+ case BUILT_IN_MEMSET_CHK:
if (VEC_length (tree, params) < 3)
return;
dest = VEC_index (tree, params, 0);
+ idx = 2;
+ break;
+ case BUILT_IN_BZERO:
+ dest = VEC_index (tree, params, 0);
+ idx = 1;
break;
case BUILT_IN_STRNDUP:
src = VEC_index (tree, params, 0);
strop = true;
+ idx = 1;
+ break;
+ case BUILT_IN_MEMCHR:
+ if (VEC_length (tree, params) < 3)
+ return;
+ src = VEC_index (tree, params, 0);
+ idx = 2;
+ break;
+ case BUILT_IN_SNPRINTF:
+ case BUILT_IN_SNPRINTF_CHK:
+ case BUILT_IN_VSNPRINTF:
+ case BUILT_IN_VSNPRINTF_CHK:
+ dest = VEC_index (tree, params, 0);
+ idx = 1;
+ strop = true;
break;
default:
break;
}
+ if (idx >= 3)
+ return;
+
+ if (sizeof_arg[idx] == NULL || sizeof_arg[idx] == error_mark_node)
+ return;
+
+ type = TYPE_P (sizeof_arg[idx])
+ ? sizeof_arg[idx] : TREE_TYPE (sizeof_arg[idx]);
+ if (!POINTER_TYPE_P (type))
+ return;
+
if (dest
&& (tem = tree_strip_nop_conversions (dest))
&& POINTER_TYPE_P (TREE_TYPE (tem))
@@ -1905,13 +1958,15 @@ sizeof_pointer_memaccess_warning (location_t loc, tree callee,
&& comp_types (TREE_TYPE (TREE_TYPE (tem)), type))
return;
- if (dest)
+ loc = sizeof_arg_loc[idx];
+
+ if (dest && !cmp)
{
- if (!TYPE_P (sizeof_arg)
- && operand_equal_p (dest, sizeof_arg, 0)
+ if (!TYPE_P (sizeof_arg[idx])
+ && operand_equal_p (dest, sizeof_arg[idx], 0)
&& comp_types (TREE_TYPE (dest), type))
{
- if (TREE_CODE (sizeof_arg) == ADDR_EXPR && !strop)
+ if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop)
warning_at (loc, OPT_Wsizeof_pointer_memaccess,
"argument to %<sizeof%> in %qD call is the same "
"expression as the destination; did you mean to "
@@ -1945,13 +2000,13 @@ sizeof_pointer_memaccess_warning (location_t loc, tree callee,
}
}
- if (src)
+ if (src && !cmp)
{
- if (!TYPE_P (sizeof_arg)
- && operand_equal_p (src, sizeof_arg, 0)
+ if (!TYPE_P (sizeof_arg[idx])
+ && operand_equal_p (src, sizeof_arg[idx], 0)
&& comp_types (TREE_TYPE (src), type))
{
- if (TREE_CODE (sizeof_arg) == ADDR_EXPR && !strop)
+ if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop)
warning_at (loc, OPT_Wsizeof_pointer_memaccess,
"argument to %<sizeof%> in %qD call is the same "
"expression as the source; did you mean to "
@@ -1984,6 +2039,87 @@ sizeof_pointer_memaccess_warning (location_t loc, tree callee,
return;
}
}
+
+ if (dest)
+ {
+ if (!TYPE_P (sizeof_arg[idx])
+ && operand_equal_p (dest, sizeof_arg[idx], 0)
+ && comp_types (TREE_TYPE (dest), type))
+ {
+ if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop)
+ warning_at (loc, OPT_Wsizeof_pointer_memaccess,
+ "argument to %<sizeof%> in %qD call is the same "
+ "expression as the first source; did you mean to "
+ "remove the addressof?", callee);
+ else if ((TYPE_PRECISION (TREE_TYPE (type))
+ == TYPE_PRECISION (char_type_node))
+ || strop)
+ warning_at (loc, OPT_Wsizeof_pointer_memaccess,
+ "argument to %<sizeof%> in %qD call is the same "
+ "expression as the first source; did you mean to "
+ "provide an explicit length?", callee);
+ else
+ warning_at (loc, OPT_Wsizeof_pointer_memaccess,
+ "argument to %<sizeof%> in %qD call is the same "
+ "expression as the first source; did you mean to "
+ "dereference it?", callee);
+ return;
+ }
+
+ if (POINTER_TYPE_P (TREE_TYPE (dest))
+ && !strop
+ && comp_types (TREE_TYPE (dest), type)
+ && !VOID_TYPE_P (TREE_TYPE (type)))
+ {
+ warning_at (loc, OPT_Wsizeof_pointer_memaccess,
+ "argument to %<sizeof%> in %qD call is the same "
+ "pointer type %qT as the first source; expected %qT "
+ "or an explicit length", callee, TREE_TYPE (dest),
+ TREE_TYPE (TREE_TYPE (dest)));
+ return;
+ }
+ }
+
+ if (src)
+ {
+ if (!TYPE_P (sizeof_arg[idx])
+ && operand_equal_p (src, sizeof_arg[idx], 0)
+ && comp_types (TREE_TYPE (src), type))
+ {
+ if (TREE_CODE (sizeof_arg[idx]) == ADDR_EXPR && !strop)
+ warning_at (loc, OPT_Wsizeof_pointer_memaccess,
+ "argument to %<sizeof%> in %qD call is the same "
+ "expression as the second source; did you mean to "
+ "remove the addressof?", callee);
+ else if ((TYPE_PRECISION (TREE_TYPE (type))
+ == TYPE_PRECISION (char_type_node))
+ || strop)
+ warning_at (loc, OPT_Wsizeof_pointer_memaccess,
+ "argument to %<sizeof%> in %qD call is the same "
+ "expression as the second source; did you mean to "
+ "provide an explicit length?", callee);
+ else
+ warning_at (loc, OPT_Wsizeof_pointer_memaccess,
+ "argument to %<sizeof%> in %qD call is the same "
+ "expression as the second source; did you mean to "
+ "dereference it?", callee);
+ return;
+ }
+
+ if (POINTER_TYPE_P (TREE_TYPE (src))
+ && !strop
+ && comp_types (TREE_TYPE (src), type)
+ && !VOID_TYPE_P (TREE_TYPE (type)))
+ {
+ warning_at (loc, OPT_Wsizeof_pointer_memaccess,
+ "argument to %<sizeof%> in %qD call is the same "
+ "pointer type %qT as the second source; expected %qT "
+ "or an explicit length", callee, TREE_TYPE (src),
+ TREE_TYPE (TREE_TYPE (src)));
+ return;
+ }
+ }
+
}
/* Warn for unlikely, improbable, or stupid DECL declarations
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index cb18b4e0747..94449a5f3f3 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -477,7 +477,9 @@ typedef enum ref_operator {
/* -> */
RO_ARROW,
/* implicit conversion */
- RO_IMPLICIT_CONVERSION
+ RO_IMPLICIT_CONVERSION,
+ /* ->* */
+ RO_ARROW_STAR
} ref_operator;
/* Information about a statement tree. */
@@ -767,8 +769,8 @@ extern tree fix_string_type (tree);
extern void constant_expression_warning (tree);
extern void constant_expression_error (tree);
extern bool strict_aliasing_warning (tree, tree, tree);
-extern void sizeof_pointer_memaccess_warning (location_t, tree,
- VEC(tree, gc) *, tree,
+extern void sizeof_pointer_memaccess_warning (location_t *, tree,
+ VEC(tree, gc) *, tree *,
bool (*) (tree, tree));
extern void warnings_for_convert_and_check (tree, tree, tree);
extern tree convert_and_check (tree, tree);
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index dfe76e63fda..89d89f7aca2 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,16 @@
+2012-10-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/54381
+ * c-parser.c (struct c_tree_loc_pair): Removed.
+ (c_parser_expr_list): Remove struct c_tree_loc_pair * argument,
+ add location_t * and tree * arguments, fill in array of 3
+ sizeof_arg trees and corresponding locs.
+ (c_parser_attributes, c_parser_objc_keywordexpr): Adjust
+ c_parser_expr_list callers.
+ (c_parser_postfix_expression_after_primary): Likewise. Pass
+ array of 3 sizeof_arg trees and locs (corresponding to first
+ 3 arguments) to sizeof_pointer_memaccess_warning.
+
2012-10-09 Lawrence Crowl <crowl@google.com>
* Make-lang.in (c-decl.o): Add dependence on hash-table.h.
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index bea9791925c..bfa98afef01 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -1111,12 +1111,6 @@ enum c_parser_prec {
NUM_PRECS
};
-/* Expression and its location. */
-struct c_tree_loc_pair {
- tree expr;
- location_t loc;
-};
-
static void c_parser_external_declaration (c_parser *);
static void c_parser_asm_definition (c_parser *);
static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
@@ -1185,8 +1179,8 @@ static tree c_parser_transaction_cancel (c_parser *);
static struct c_expr c_parser_expression (c_parser *);
static struct c_expr c_parser_expression_conv (c_parser *);
static VEC(tree,gc) *c_parser_expr_list (c_parser *, bool, bool,
- VEC(tree,gc) **,
- struct c_tree_loc_pair *);
+ VEC(tree,gc) **, location_t *,
+ tree *);
static void c_parser_omp_construct (c_parser *);
static void c_parser_omp_threadprivate (c_parser *);
static void c_parser_omp_barrier (c_parser *);
@@ -3586,7 +3580,7 @@ c_parser_attributes (c_parser *parser)
tree tree_list;
c_parser_consume_token (parser);
expr_list = c_parser_expr_list (parser, false, true,
- NULL, NULL);
+ NULL, NULL, NULL);
tree_list = build_tree_list_vec (expr_list);
attr_args = tree_cons (NULL_TREE, arg1, tree_list);
release_tree_vector (expr_list);
@@ -3599,7 +3593,7 @@ c_parser_attributes (c_parser *parser)
else
{
expr_list = c_parser_expr_list (parser, false, true,
- NULL, NULL);
+ NULL, NULL, NULL);
attr_args = build_tree_list_vec (expr_list);
release_tree_vector (expr_list);
}
@@ -6875,7 +6869,9 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
{
struct c_expr orig_expr;
tree ident, idx;
- struct c_tree_loc_pair sizeof_arg;
+ location_t sizeof_arg_loc[3];
+ tree sizeof_arg[3];
+ unsigned int i;
VEC(tree,gc) *exprlist;
VEC(tree,gc) *origtypes;
while (true)
@@ -6896,21 +6892,24 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
case CPP_OPEN_PAREN:
/* Function call. */
c_parser_consume_token (parser);
- sizeof_arg.expr = NULL_TREE;
+ for (i = 0; i < 3; i++)
+ {
+ sizeof_arg[i] = NULL_TREE;
+ sizeof_arg_loc[i] = UNKNOWN_LOCATION;
+ }
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
exprlist = NULL;
else
exprlist = c_parser_expr_list (parser, true, false, &origtypes,
- &sizeof_arg);
+ sizeof_arg_loc, sizeof_arg);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
orig_expr = expr;
mark_exp_read (expr.value);
- if (warn_sizeof_pointer_memaccess
- && sizeof_arg.expr != NULL_TREE)
- sizeof_pointer_memaccess_warning (sizeof_arg.loc,
+ if (warn_sizeof_pointer_memaccess)
+ sizeof_pointer_memaccess_warning (sizeof_arg_loc,
expr.value, exprlist,
- sizeof_arg.expr,
+ sizeof_arg,
sizeof_ptr_memacc_comptypes);
/* FIXME diagnostics: Ideally we want the FUNCNAME, not the
"(" after the FUNCNAME, which is what we have now. */
@@ -7072,14 +7071,15 @@ c_parser_expression_conv (c_parser *parser)
static VEC(tree,gc) *
c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
- VEC(tree,gc) **p_orig_types,
- struct c_tree_loc_pair *sizeof_arg)
+ VEC(tree,gc) **p_orig_types, location_t *sizeof_arg_loc,
+ tree *sizeof_arg)
{
VEC(tree,gc) *ret;
VEC(tree,gc) *orig_types;
struct c_expr expr;
location_t loc = c_parser_peek_token (parser)->location;
- location_t sizeof_arg_loc = UNKNOWN_LOCATION;
+ location_t cur_sizeof_arg_loc = UNKNOWN_LOCATION;
+ unsigned int idx = 0;
ret = make_tree_vector ();
if (p_orig_types == NULL)
@@ -7089,7 +7089,7 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
if (sizeof_arg != NULL
&& c_parser_next_token_is_keyword (parser, RID_SIZEOF))
- sizeof_arg_loc = c_parser_peek_2nd_token (parser)->location;
+ cur_sizeof_arg_loc = c_parser_peek_2nd_token (parser)->location;
expr = c_parser_expr_no_commas (parser, NULL);
if (convert_p)
expr = default_function_array_read_conversion (loc, expr);
@@ -7098,15 +7098,22 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
VEC_quick_push (tree, ret, expr.value);
if (orig_types != NULL)
VEC_quick_push (tree, orig_types, expr.original_type);
+ if (sizeof_arg != NULL
+ && cur_sizeof_arg_loc != UNKNOWN_LOCATION
+ && expr.original_code == SIZEOF_EXPR)
+ {
+ sizeof_arg[0] = c_last_sizeof_arg;
+ sizeof_arg_loc[0] = cur_sizeof_arg_loc;
+ }
while (c_parser_next_token_is (parser, CPP_COMMA))
{
c_parser_consume_token (parser);
loc = c_parser_peek_token (parser)->location;
if (sizeof_arg != NULL
&& c_parser_next_token_is_keyword (parser, RID_SIZEOF))
- sizeof_arg_loc = c_parser_peek_2nd_token (parser)->location;
+ cur_sizeof_arg_loc = c_parser_peek_2nd_token (parser)->location;
else
- sizeof_arg_loc = UNKNOWN_LOCATION;
+ cur_sizeof_arg_loc = UNKNOWN_LOCATION;
expr = c_parser_expr_no_commas (parser, NULL);
if (convert_p)
expr = default_function_array_read_conversion (loc, expr);
@@ -7115,19 +7122,13 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
VEC_safe_push (tree, gc, ret, expr.value);
if (orig_types != NULL)
VEC_safe_push (tree, gc, orig_types, expr.original_type);
- }
- if (sizeof_arg != NULL)
- {
- if (sizeof_arg_loc != UNKNOWN_LOCATION
+ if (++idx < 3
+ && sizeof_arg != NULL
+ && cur_sizeof_arg_loc != UNKNOWN_LOCATION
&& expr.original_code == SIZEOF_EXPR)
{
- sizeof_arg->expr = c_last_sizeof_arg;
- sizeof_arg->loc = sizeof_arg_loc;
- }
- else
- {
- sizeof_arg->expr = NULL_TREE;
- sizeof_arg->loc = UNKNOWN_LOCATION;
+ sizeof_arg[idx] = c_last_sizeof_arg;
+ sizeof_arg_loc[idx] = cur_sizeof_arg_loc;
}
}
if (orig_types != NULL)
@@ -8209,7 +8210,7 @@ c_parser_objc_keywordexpr (c_parser *parser)
{
tree ret;
VEC(tree,gc) *expr_list = c_parser_expr_list (parser, true, true,
- NULL, NULL);
+ NULL, NULL, NULL);
if (VEC_length (tree, expr_list) == 1)
{
/* Just return the expression, remove a level of
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 80af7d8dbc4..95f5d5313da 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -254,7 +254,8 @@ extern basic_block *get_loop_body_in_custom_order (const struct loop *,
int (*) (const void *, const void *));
extern VEC (edge, heap) *get_loop_exit_edges (const struct loop *);
-edge single_exit (const struct loop *);
+extern edge single_exit (const struct loop *);
+extern edge single_likely_exit (struct loop *loop);
extern unsigned num_loop_branches (const struct loop *);
extern edge loop_preheader_edge (const struct loop *);
diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
index cec33fbb97e..c3cf3edf9b9 100644
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -446,3 +446,40 @@ mark_loop_exit_edges (void)
}
}
+/* Return exit edge if loop has only one exit that is likely
+ to be executed on runtime (i.e. it is not EH or leading
+ to noreturn call. */
+
+edge
+single_likely_exit (struct loop *loop)
+{
+ edge found = single_exit (loop);
+ VEC (edge, heap) *exits;
+ unsigned i;
+ edge ex;
+
+ if (found)
+ return found;
+ exits = get_loop_exit_edges (loop);
+ FOR_EACH_VEC_ELT (edge, exits, i, ex)
+ {
+ if (ex->flags & (EDGE_EH | EDGE_ABNORMAL_CALL))
+ continue;
+ /* The constant of 5 is set in a way so noreturn calls are
+ ruled out by this test. The static branch prediction algorithm
+ will not assign such a low probability to conditionals for usual
+ reasons. */
+ if (profile_status != PROFILE_ABSENT
+ && ex->probability < 5 && !ex->count)
+ continue;
+ if (!found)
+ found = ex;
+ else
+ {
+ VEC_free (edge, heap, exits);
+ return NULL;
+ }
+ }
+ VEC_free (edge, heap, exits);
+ return found;
+}
diff --git a/gcc/combine.c b/gcc/combine.c
index 4e0a57963dc..c13d00408ad 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -12015,8 +12015,8 @@ count_rtxs (rtx x)
const char *fmt;
int i, j, ret = 1;
- if (GET_RTX_CLASS (code) == '2'
- || GET_RTX_CLASS (code) == 'c')
+ if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
+ || GET_RTX_CLASS (code) == RTX_COMM_ARITH)
{
rtx x0 = XEXP (x, 0);
rtx x1 = XEXP (x, 1);
@@ -12024,15 +12024,15 @@ count_rtxs (rtx x)
if (x0 == x1)
return 1 + 2 * count_rtxs (x0);
- if ((GET_RTX_CLASS (GET_CODE (x1)) == '2'
- || GET_RTX_CLASS (GET_CODE (x1)) == 'c')
+ if ((GET_RTX_CLASS (GET_CODE (x1)) == RTX_BIN_ARITH
+ || GET_RTX_CLASS (GET_CODE (x1)) == RTX_COMM_ARITH)
&& (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
return 2 + 2 * count_rtxs (x0)
+ count_rtxs (x == XEXP (x1, 0)
? XEXP (x1, 1) : XEXP (x1, 0));
- if ((GET_RTX_CLASS (GET_CODE (x0)) == '2'
- || GET_RTX_CLASS (GET_CODE (x0)) == 'c')
+ if ((GET_RTX_CLASS (GET_CODE (x0)) == RTX_BIN_ARITH
+ || GET_RTX_CLASS (GET_CODE (x0)) == RTX_COMM_ARITH)
&& (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
return 2 + 2 * count_rtxs (x1)
+ count_rtxs (x == XEXP (x0, 0)
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index d726b5acca7..82135ffda3d 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -963,7 +963,7 @@ alpha_legitimize_address_1 (rtx x, rtx scratch, enum machine_mode mode)
scratch = gen_reg_rtx (Pmode);
dest = gen_reg_rtx (Pmode);
- emit_insn (gen_load_tp (tp));
+ emit_insn (gen_get_thread_pointerdi (tp));
emit_insn (gen_rtx_SET (VOIDmode, scratch, eqv));
emit_insn (gen_adddi3 (dest, tp, scratch));
return dest;
@@ -973,7 +973,7 @@ alpha_legitimize_address_1 (rtx x, rtx scratch, enum machine_mode mode)
eqv = gen_rtx_CONST (Pmode, eqv);
tp = gen_reg_rtx (Pmode);
- emit_insn (gen_load_tp (tp));
+ emit_insn (gen_get_thread_pointerdi (tp));
if (alpha_tls_size == 32)
{
insn = gen_rtx_HIGH (Pmode, eqv);
@@ -6328,8 +6328,6 @@ enum alpha_builtin
ALPHA_BUILTIN_AMASK,
ALPHA_BUILTIN_IMPLVER,
ALPHA_BUILTIN_RPCC,
- ALPHA_BUILTIN_THREAD_POINTER,
- ALPHA_BUILTIN_SET_THREAD_POINTER,
ALPHA_BUILTIN_ESTABLISH_VMS_CONDITION_HANDLER,
ALPHA_BUILTIN_REVERT_VMS_CONDITION_HANDLER,
@@ -6385,8 +6383,6 @@ static enum insn_code const code_for_builtin[ALPHA_BUILTIN_max] = {
CODE_FOR_builtin_amask,
CODE_FOR_builtin_implver,
CODE_FOR_builtin_rpcc,
- CODE_FOR_load_tp,
- CODE_FOR_set_tp,
CODE_FOR_builtin_establish_vms_condition_handler,
CODE_FOR_builtin_revert_vms_condition_handler,
@@ -6544,14 +6540,6 @@ alpha_init_builtins (void)
alpha_dimode_u, NULL_TREE);
alpha_add_builtins (two_arg_builtins, ARRAY_SIZE (two_arg_builtins), ftype);
- ftype = build_function_type_list (ptr_type_node, NULL_TREE);
- alpha_builtin_function ("__builtin_thread_pointer", ftype,
- ALPHA_BUILTIN_THREAD_POINTER, ECF_NOTHROW);
-
- ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
- alpha_builtin_function ("__builtin_set_thread_pointer", ftype,
- ALPHA_BUILTIN_SET_THREAD_POINTER, ECF_NOTHROW);
-
if (TARGET_ABI_OPEN_VMS)
{
ftype = build_function_type_list (ptr_type_node, ptr_type_node,
@@ -7088,8 +7076,6 @@ alpha_fold_builtin (tree fndecl, int n_args, tree *op,
case ALPHA_BUILTIN_AMASK:
case ALPHA_BUILTIN_IMPLVER:
case ALPHA_BUILTIN_RPCC:
- case ALPHA_BUILTIN_THREAD_POINTER:
- case ALPHA_BUILTIN_SET_THREAD_POINTER:
/* None of these are foldable at compile-time. */
default:
return NULL;
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index 21c4d2e0554..1aa8a6714ae 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -90,9 +90,23 @@
(define_mode_attr reloadmode [(QI "qi") (HI "hi") (CQI "hi")])
;; Other mode iterators
+(define_mode_iterator IMODE [QI HI SI DI])
(define_mode_iterator I12MODE [QI HI])
+(define_mode_iterator I124MODE [QI HI SI])
+(define_mode_iterator I24MODE [HI SI])
+(define_mode_iterator I248MODE [HI SI DI])
(define_mode_iterator I48MODE [SI DI])
-(define_mode_attr modesuffix [(SI "l") (DI "q")])
+
+(define_mode_attr DWI [(SI "DI") (DI "TI")])
+(define_mode_attr modesuffix [(QI "b") (HI "w") (SI "l") (DI "q")
+ (V8QI "b8") (V4HI "w4")
+ (SF "%,") (DF "%-")])
+(define_mode_attr vecmodesuffix [(QI "b8") (HI "w4")])
+
+(define_code_iterator any_maxmin [smax smin umax umin])
+
+(define_code_attr maxmin [(smax "maxs") (smin "mins")
+ (umax "maxu") (umin "minu")])
;; Where necessary, the suffixes _le and _be are used to distinguish between
;; little-endian and big-endian patterns.
@@ -220,10 +234,8 @@
;; code for that case. But we don't reject the possibility.
(define_expand "extendsidi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
- ""
- "")
+ [(set (match_operand:DI 0 "register_operand")
+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
(define_insn "*cvtlq"
[(set (match_operand:DI 0 "register_operand" "=f")
@@ -246,8 +258,8 @@
(set_attr "length" "*,*,8")])
(define_split
- [(set (match_operand:DI 0 "hard_fp_register_operand" "")
- (sign_extend:DI (match_operand:SI 1 "memory_operand" "")))]
+ [(set (match_operand:DI 0 "hard_fp_register_operand")
+ (sign_extend:DI (match_operand:SI 1 "memory_operand")))]
"reload_completed"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (unspec:DI [(match_dup 2)] UNSPEC_CVTLQ))]
@@ -260,15 +272,14 @@
;; reload when converting fp->int.
(define_peephole2
- [(set (match_operand:SI 0 "hard_int_register_operand" "")
- (match_operand:SI 1 "memory_operand" ""))
- (set (match_operand:DI 2 "hard_int_register_operand" "")
+ [(set (match_operand:SI 0 "hard_int_register_operand")
+ (match_operand:SI 1 "memory_operand"))
+ (set (match_operand:DI 2 "hard_int_register_operand")
(sign_extend:DI (match_dup 0)))]
"true_regnum (operands[0]) == true_regnum (operands[2])
|| peep2_reg_dead_p (2, operands[0])"
[(set (match_dup 2)
- (sign_extend:DI (match_dup 1)))]
- "")
+ (sign_extend:DI (match_dup 1)))])
(define_insn "addsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
@@ -282,9 +293,9 @@
ldah %0,%h2(%r1)")
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (plus:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "const_int_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (plus:SI (match_operand:SI 1 "register_operand")
+ (match_operand:SI 2 "const_int_operand")))]
"! add_operand (operands[2], SImode)"
[(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
@@ -319,11 +330,11 @@
subl %r1,%n2,%0")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(sign_extend:DI
- (plus:SI (match_operand:SI 1 "reg_not_elim_operand" "")
- (match_operand:SI 2 "const_int_operand" ""))))
- (clobber (match_operand:SI 3 "reg_not_elim_operand" ""))]
+ (plus:SI (match_operand:SI 1 "reg_not_elim_operand")
+ (match_operand:SI 2 "const_int_operand"))))
+ (clobber (match_operand:SI 3 "reg_not_elim_operand"))]
"! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
&& INTVAL (operands[2]) % 4 == 0"
[(set (match_dup 3) (match_dup 4))
@@ -342,13 +353,13 @@
})
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(sign_extend:DI
(plus:SI (match_operator:SI 1 "comparison_operator"
- [(match_operand 2 "" "")
- (match_operand 3 "" "")])
- (match_operand:SI 4 "add_operand" ""))))
- (clobber (match_operand:DI 5 "register_operand" ""))]
+ [(match_operand 2)
+ (match_operand 3)])
+ (match_operand:SI 4 "add_operand"))))
+ (clobber (match_operand:DI 5 "register_operand"))]
""
[(set (match_dup 5) (match_dup 6))
(set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]
@@ -358,80 +369,64 @@
operands[7] = gen_lowpart (SImode, operands[5]);
})
-(define_insn "addvsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
- (match_operand:SI 2 "sext_add_operand" "rI,O")))
- (trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
- (sign_extend:DI (match_dup 2)))
- (sign_extend:DI (plus:SI (match_dup 1)
- (match_dup 2))))
- (const_int 0))]
- ""
- "@
- addlv %r1,%2,%0
- sublv %r1,%n2,%0")
-
(define_expand "adddi3"
- [(set (match_operand:DI 0 "register_operand" "")
- (plus:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "add_operand" "")))]
- ""
- "")
+ [(set (match_operand:DI 0 "register_operand")
+ (plus:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "add_operand")))])
(define_insn "*adddi_er_lo16_dtp"
[(set (match_operand:DI 0 "register_operand" "=r")
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "dtp16_symbolic_operand" "")))]
+ (match_operand:DI 2 "dtp16_symbolic_operand")))]
"HAVE_AS_TLS"
"lda %0,%2(%1)\t\t!dtprel")
(define_insn "*adddi_er_hi32_dtp"
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (match_operand:DI 1 "register_operand" "r")
- (high:DI (match_operand:DI 2 "dtp32_symbolic_operand" ""))))]
+ (high:DI (match_operand:DI 2 "dtp32_symbolic_operand"))))]
"HAVE_AS_TLS"
"ldah %0,%2(%1)\t\t!dtprelhi")
(define_insn "*adddi_er_lo32_dtp"
[(set (match_operand:DI 0 "register_operand" "=r")
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "dtp32_symbolic_operand" "")))]
+ (match_operand:DI 2 "dtp32_symbolic_operand")))]
"HAVE_AS_TLS"
"lda %0,%2(%1)\t\t!dtprello")
(define_insn "*adddi_er_lo16_tp"
[(set (match_operand:DI 0 "register_operand" "=r")
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "tp16_symbolic_operand" "")))]
+ (match_operand:DI 2 "tp16_symbolic_operand")))]
"HAVE_AS_TLS"
"lda %0,%2(%1)\t\t!tprel")
(define_insn "*adddi_er_hi32_tp"
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (match_operand:DI 1 "register_operand" "r")
- (high:DI (match_operand:DI 2 "tp32_symbolic_operand" ""))))]
+ (high:DI (match_operand:DI 2 "tp32_symbolic_operand"))))]
"HAVE_AS_TLS"
"ldah %0,%2(%1)\t\t!tprelhi")
(define_insn "*adddi_er_lo32_tp"
[(set (match_operand:DI 0 "register_operand" "=r")
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "tp32_symbolic_operand" "")))]
+ (match_operand:DI 2 "tp32_symbolic_operand")))]
"HAVE_AS_TLS"
"lda %0,%2(%1)\t\t!tprello")
(define_insn "*adddi_er_high_l"
[(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (match_operand:DI 1 "register_operand" "r")
- (high:DI (match_operand:DI 2 "local_symbolic_operand" ""))))]
+ (high:DI (match_operand:DI 2 "local_symbolic_operand"))))]
"TARGET_EXPLICIT_RELOCS && reload_completed"
"ldah %0,%2(%1)\t\t!gprelhigh"
[(set_attr "usegp" "yes")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (high:DI (match_operand:DI 1 "local_symbolic_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (high:DI (match_operand:DI 1 "local_symbolic_operand")))]
"TARGET_EXPLICIT_RELOCS && reload_completed"
[(set (match_dup 0)
(plus:DI (match_dup 2) (high:DI (match_dup 1))))]
@@ -493,9 +488,9 @@
;; Don't do this if we are adjusting SP since we don't want to do it
;; in two steps. Don't split FP sources for the reason listed above.
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (plus:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "const_int_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (plus:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "const_int_operand")))]
"! add_operand (operands[2], DImode)
&& operands[0] != stack_pointer_rtx
&& operands[1] != frame_pointer_rtx
@@ -522,15 +517,16 @@
FAIL;
})
-(define_insn "*saddl"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
- (match_operand:SI 2 "const48_operand" "I,I"))
- (match_operand:SI 3 "sext_add_operand" "rI,O")))]
+(define_insn "*sadd<modesuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
+ (plus:I48MODE
+ (mult:I48MODE (match_operand:I48MODE 1 "reg_not_elim_operand" "r,r")
+ (match_operand:I48MODE 2 "const48_operand" "I,I"))
+ (match_operand:I48MODE 3 "sext_add_operand" "rI,O")))]
""
"@
- s%2addl %1,%3,%0
- s%2subl %1,%n3,%0")
+ s%2add<modesuffix> %1,%3,%0
+ s%2sub<modesuffix> %1,%n3,%0")
(define_insn "*saddl_se"
[(set (match_operand:DI 0 "register_operand" "=r,r")
@@ -544,14 +540,14 @@
s%2subl %1,%n3,%0")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(sign_extend:DI
(plus:SI (mult:SI (match_operator:SI 1 "comparison_operator"
- [(match_operand 2 "" "")
- (match_operand 3 "" "")])
- (match_operand:SI 4 "const48_operand" ""))
- (match_operand:SI 5 "sext_add_operand" ""))))
- (clobber (match_operand:DI 6 "reg_not_elim_operand" ""))]
+ [(match_operand 2)
+ (match_operand 3)])
+ (match_operand:SI 4 "const48_operand"))
+ (match_operand:SI 5 "sext_add_operand"))))
+ (clobber (match_operand:DI 6 "reg_not_elim_operand"))]
""
[(set (match_dup 6) (match_dup 7))
(set (match_dup 0)
@@ -563,35 +559,25 @@
operands[8] = gen_lowpart (SImode, operands[6]);
})
-(define_insn "*saddq"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (plus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r")
- (match_operand:DI 2 "const48_operand" "I,I"))
- (match_operand:DI 3 "sext_add_operand" "rI,O")))]
- ""
- "@
- s%2addq %1,%3,%0
- s%2subq %1,%n3,%0")
-
-(define_insn "addvdi3"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
- (match_operand:DI 2 "sext_add_operand" "rI,O")))
- (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
- (sign_extend:TI (match_dup 2)))
- (sign_extend:TI (plus:DI (match_dup 1)
- (match_dup 2))))
+(define_insn "addv<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
+ (plus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rJ,rJ")
+ (match_operand:I48MODE 2 "sext_add_operand" "rI,O")))
+ (trap_if (ne (plus:<DWI> (sign_extend:<DWI> (match_dup 1))
+ (sign_extend:<DWI> (match_dup 2)))
+ (sign_extend:<DWI> (plus:I48MODE (match_dup 1)
+ (match_dup 2))))
(const_int 0))]
""
"@
- addqv %r1,%2,%0
- subqv %r1,%n2,%0")
+ add<modesuffix>v %r1,%2,%0
+ sub<modesuffix>v %r1,%n2,%0")
-(define_insn "negsi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
+(define_insn "neg<mode>2"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (neg:I48MODE (match_operand:I48MODE 1 "reg_or_8bit_operand" "rI")))]
""
- "subl $31,%1,%0")
+ "sub<modesuffix> $31,%1,%0")
(define_insn "*negsi_se"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -600,41 +586,27 @@
""
"subl $31,%1,%0")
-(define_insn "negvsi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (neg:SI (match_operand:SI 1 "register_operand" "r")))
- (trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
- (sign_extend:DI (neg:SI (match_dup 1))))
+(define_insn "negv<mode>2"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (neg:I48MODE (match_operand:I48MODE 1 "register_operand" "r")))
+ (trap_if (ne (neg:<DWI> (sign_extend:<DWI> (match_dup 1)))
+ (sign_extend:<DWI> (neg:I48MODE (match_dup 1))))
(const_int 0))]
""
- "sublv $31,%1,%0")
+ "sub<modesuffix>v $31,%1,%0")
-(define_insn "negdi2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
+(define_insn "sub<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (minus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rJ")
+ (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))]
""
- "subq $31,%1,%0")
-
-(define_insn "negvdi2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (neg:DI (match_operand:DI 1 "register_operand" "r")))
- (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
- (sign_extend:TI (neg:DI (match_dup 1))))
- (const_int 0))]
- ""
- "subqv $31,%1,%0")
-
-(define_insn "subsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
- (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
- ""
- "subl %r1,%2,%0")
+ "sub<modesuffix> %r1,%2,%0")
(define_insn "*subsi_se"
[(set (match_operand:DI 0 "register_operand" "=r")
- (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
- (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
+ (sign_extend:DI
+ (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
+ (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
""
"subl %r1,%2,%0")
@@ -647,32 +619,14 @@
""
"subl %r1,%2,%0")
-(define_insn "subvsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
- (match_operand:SI 2 "reg_or_8bit_operand" "rI")))
- (trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
- (sign_extend:DI (match_dup 2)))
- (sign_extend:DI (minus:SI (match_dup 1)
- (match_dup 2))))
- (const_int 0))]
- ""
- "sublv %r1,%2,%0")
-
-(define_insn "subdi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
- (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
+(define_insn "*ssub<modesuffix>"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (minus:I48MODE
+ (mult:I48MODE (match_operand:I48MODE 1 "reg_not_elim_operand" "r")
+ (match_operand:I48MODE 2 "const48_operand" "I"))
+ (match_operand:I48MODE 3 "reg_or_8bit_operand" "rI")))]
""
- "subq %r1,%2,%0")
-
-(define_insn "*ssubl"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
- (match_operand:SI 2 "const48_operand" "I"))
- (match_operand:SI 3 "reg_or_8bit_operand" "rI")))]
- ""
- "s%2subl %1,%3,%0")
+ "s%2sub<modesuffix> %1,%3,%0")
(define_insn "*ssubl_se"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -683,34 +637,26 @@
""
"s%2subl %1,%3,%0")
-(define_insn "*ssubq"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (minus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r")
- (match_operand:DI 2 "const48_operand" "I"))
- (match_operand:DI 3 "reg_or_8bit_operand" "rI")))]
- ""
- "s%2subq %1,%3,%0")
-
-(define_insn "subvdi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
- (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
- (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
- (sign_extend:TI (match_dup 2)))
- (sign_extend:TI (minus:DI (match_dup 1)
- (match_dup 2))))
+(define_insn "subv<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (minus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rJ")
+ (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))
+ (trap_if (ne (minus:<DWI> (sign_extend:<DWI> (match_dup 1))
+ (sign_extend:<DWI> (match_dup 2)))
+ (sign_extend:<DWI> (minus:I48MODE (match_dup 1)
+ (match_dup 2))))
(const_int 0))]
""
- "subqv %r1,%2,%0")
+ "sub<modesuffix>v %r1,%2,%0")
-(define_insn "mulsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
- (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
+(define_insn "mul<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (mult:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rJ")
+ (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))]
""
- "mull %r1,%2,%0"
+ "mul<modesuffix> %r1,%2,%0"
[(set_attr "type" "imul")
- (set_attr "opsize" "si")])
+ (set_attr "opsize" "<mode>")])
(define_insn "*mulsi_se"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -722,48 +668,27 @@
[(set_attr "type" "imul")
(set_attr "opsize" "si")])
-(define_insn "mulvsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
- (match_operand:SI 2 "reg_or_8bit_operand" "rI")))
- (trap_if (ne (mult:DI (sign_extend:DI (match_dup 1))
- (sign_extend:DI (match_dup 2)))
- (sign_extend:DI (mult:SI (match_dup 1)
- (match_dup 2))))
+(define_insn "mulv<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (mult:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rJ")
+ (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))
+ (trap_if (ne (mult:<DWI> (sign_extend:<DWI> (match_dup 1))
+ (sign_extend:<DWI> (match_dup 2)))
+ (sign_extend:<DWI> (mult:I48MODE (match_dup 1)
+ (match_dup 2))))
(const_int 0))]
""
- "mullv %r1,%2,%0"
+ "mul<modesuffix>v %r1,%2,%0"
[(set_attr "type" "imul")
- (set_attr "opsize" "si")])
-
-(define_insn "muldi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
- (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
- ""
- "mulq %r1,%2,%0"
- [(set_attr "type" "imul")])
-
-(define_insn "mulvdi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
- (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
- (trap_if (ne (mult:TI (sign_extend:TI (match_dup 1))
- (sign_extend:TI (match_dup 2)))
- (sign_extend:TI (mult:DI (match_dup 1)
- (match_dup 2))))
- (const_int 0))]
- ""
- "mulqv %r1,%2,%0"
- [(set_attr "type" "imul")])
+ (set_attr "opsize" "<mode>")])
(define_expand "umuldi3_highpart"
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(truncate:DI
(lshiftrt:TI
(mult:TI (zero_extend:TI
- (match_operand:DI 1 "register_operand" ""))
- (match_operand:DI 2 "reg_or_8bit_operand" ""))
+ (match_operand:DI 1 "register_operand"))
+ (match_operand:DI 2 "reg_or_8bit_operand"))
(const_int 64))))]
""
{
@@ -806,34 +731,19 @@
;; problem. Is it worth the complication here to eliminate the sign
;; extension?
-(define_expand "divsi3"
- [(set (match_dup 3)
- (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
- (set (match_dup 4)
- (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
- (parallel [(set (match_dup 5)
- (sign_extend:DI (div:SI (match_dup 3) (match_dup 4))))
- (clobber (reg:DI 23))
- (clobber (reg:DI 28))])
- (set (match_operand:SI 0 "nonimmediate_operand" "")
- (subreg:SI (match_dup 5) 0))]
- "TARGET_ABI_OSF"
-{
- operands[3] = gen_reg_rtx (DImode);
- operands[4] = gen_reg_rtx (DImode);
- operands[5] = gen_reg_rtx (DImode);
-})
+(define_code_iterator any_divmod [div mod udiv umod])
-(define_expand "udivsi3"
+(define_expand "<code>si3"
[(set (match_dup 3)
- (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand")))
(set (match_dup 4)
- (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
+ (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand")))
(parallel [(set (match_dup 5)
- (sign_extend:DI (udiv:SI (match_dup 3) (match_dup 4))))
+ (sign_extend:DI
+ (any_divmod:SI (match_dup 3) (match_dup 4))))
(clobber (reg:DI 23))
(clobber (reg:DI 28))])
- (set (match_operand:SI 0 "nonimmediate_operand" "")
+ (set (match_operand:SI 0 "nonimmediate_operand")
(subreg:SI (match_dup 5) 0))]
"TARGET_ABI_OSF"
{
@@ -842,77 +752,14 @@
operands[5] = gen_reg_rtx (DImode);
})
-(define_expand "modsi3"
- [(set (match_dup 3)
- (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
- (set (match_dup 4)
- (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
- (parallel [(set (match_dup 5)
- (sign_extend:DI (mod:SI (match_dup 3) (match_dup 4))))
- (clobber (reg:DI 23))
- (clobber (reg:DI 28))])
- (set (match_operand:SI 0 "nonimmediate_operand" "")
- (subreg:SI (match_dup 5) 0))]
- "TARGET_ABI_OSF"
-{
- operands[3] = gen_reg_rtx (DImode);
- operands[4] = gen_reg_rtx (DImode);
- operands[5] = gen_reg_rtx (DImode);
-})
-
-(define_expand "umodsi3"
- [(set (match_dup 3)
- (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
- (set (match_dup 4)
- (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
- (parallel [(set (match_dup 5)
- (sign_extend:DI (umod:SI (match_dup 3) (match_dup 4))))
- (clobber (reg:DI 23))
- (clobber (reg:DI 28))])
- (set (match_operand:SI 0 "nonimmediate_operand" "")
- (subreg:SI (match_dup 5) 0))]
- "TARGET_ABI_OSF"
-{
- operands[3] = gen_reg_rtx (DImode);
- operands[4] = gen_reg_rtx (DImode);
- operands[5] = gen_reg_rtx (DImode);
-})
-
-(define_expand "divdi3"
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (div:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))
+(define_expand "<code>di3"
+ [(parallel [(set (match_operand:DI 0 "register_operand")
+ (any_divmod:DI
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "register_operand")))
(clobber (reg:DI 23))
(clobber (reg:DI 28))])]
- "TARGET_ABI_OSF"
- "")
-
-(define_expand "udivdi3"
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (udiv:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))
- (clobber (reg:DI 23))
- (clobber (reg:DI 28))])]
- "TARGET_ABI_OSF"
- "")
-
-(define_expand "moddi3"
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (mod:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))
- (clobber (reg:DI 23))
- (clobber (reg:DI 28))])]
- "TARGET_ABI_OSF"
- "")
-
-(define_expand "umoddi3"
- [(parallel [(set (match_operand:DI 0 "register_operand" "")
- (umod:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "register_operand" "")))
- (clobber (reg:DI 23))
- (clobber (reg:DI 28))])]
- "TARGET_ABI_OSF"
- "")
+ "TARGET_ABI_OSF")
;; Lengths of 8 for ldq $t12,__divq($gp); jsr $t9,($t12),__divq as
;; expanded by the assembler.
@@ -966,7 +813,7 @@
[(match_operand:DI 1 "register_operand" "a")
(match_operand:DI 2 "register_operand" "b")])))
(use (match_operand:DI 4 "register_operand" "c"))
- (use (match_operand 5 "const_int_operand" ""))
+ (use (match_operand 5 "const_int_operand"))
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
@@ -1034,7 +881,7 @@
[(match_operand:DI 1 "register_operand" "a")
(match_operand:DI 2 "register_operand" "b")]))
(use (match_operand:DI 4 "register_operand" "c"))
- (use (match_operand 5 "const_int_operand" ""))
+ (use (match_operand 5 "const_int_operand"))
(clobber (reg:DI 23))
(clobber (reg:DI 28))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
@@ -1087,9 +934,9 @@
;; too messy otherwise.
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (and:DI (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "const_int_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (and:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "const_int_operand")))]
"HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)"
[(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
(set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
@@ -1110,31 +957,9 @@
operands[4] = GEN_INT (mask2);
})
-(define_insn "zero_extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (zero_extend:HI
- (match_operand:QI 1 "reg_or_bwx_memory_operand" "r,m")))]
- ""
- "@
- and %1,0xff,%0
- ldbu %0,%1"
- [(set_attr "type" "ilog,ild")
- (set_attr "isa" "*,bwx")])
-
-(define_insn "zero_extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (zero_extend:SI
- (match_operand:QI 1 "reg_or_bwx_memory_operand" "r,m")))]
- ""
- "@
- and %1,0xff,%0
- ldbu %0,%1"
- [(set_attr "type" "ilog,ild")
- (set_attr "isa" "*,bwx")])
-
-(define_insn "zero_extendqidi2"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (zero_extend:DI
+(define_insn "zero_extendqi<mode>2"
+ [(set (match_operand:I248MODE 0 "register_operand" "=r,r")
+ (zero_extend:I248MODE
(match_operand:QI 1 "reg_or_bwx_memory_operand" "r,m")))]
""
"@
@@ -1143,20 +968,9 @@
[(set_attr "type" "ilog,ild")
(set_attr "isa" "*,bwx")])
-(define_insn "zero_extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (zero_extend:SI
- (match_operand:HI 1 "reg_or_bwx_memory_operand" "r,m")))]
- ""
- "@
- zapnot %1,3,%0
- ldwu %0,%1"
- [(set_attr "type" "shift,ild")
- (set_attr "isa" "*,bwx")])
-
-(define_insn "zero_extendhidi2"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (zero_extend:DI
+(define_insn "zero_extendhi<mode>2"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
+ (zero_extend:I48MODE
(match_operand:HI 1 "reg_or_bwx_memory_operand" "r,m")))]
""
"@
@@ -1172,18 +986,11 @@
"zapnot %1,15,%0"
[(set_attr "type" "shift")])
-(define_insn "*andnotsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (and:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI"))
- (match_operand:SI 2 "reg_or_0_operand" "rJ")))]
- ""
- "bic %r2,%1,%0"
- [(set_attr "type" "ilog")])
-
-(define_insn "andnotdi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
- (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
+(define_insn "andnot<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (and:I48MODE
+ (not:I48MODE (match_operand:I48MODE 1 "reg_or_8bit_operand" "rI"))
+ (match_operand:I48MODE 2 "reg_or_0_operand" "rJ")))]
""
"bic %r2,%1,%0"
[(set_attr "type" "ilog")])
@@ -1222,18 +1029,11 @@
"ornot $31,%1,%0"
[(set_attr "type" "ilog")])
-(define_insn "*iornotsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ior:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI"))
- (match_operand:SI 2 "reg_or_0_operand" "rJ")))]
- ""
- "ornot %r2,%1,%0"
- [(set_attr "type" "ilog")])
-
-(define_insn "*iornotdi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
- (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
+(define_insn "*iornot<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (ior:I48MODE
+ (not:I48MODE (match_operand:I48MODE 1 "reg_or_8bit_operand" "rI"))
+ (match_operand:I48MODE 2 "reg_or_0_operand" "rJ")))]
""
"ornot %r2,%1,%0"
[(set_attr "type" "ilog")])
@@ -1258,18 +1058,11 @@
eqv %r1,%N2,%0"
[(set_attr "type" "ilog")])
-(define_insn "*xornotsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (not:SI (xor:SI (match_operand:SI 1 "register_operand" "%rJ")
- (match_operand:SI 2 "register_operand" "rI"))))]
- ""
- "eqv %r1,%2,%0"
- [(set_attr "type" "ilog")])
-
-(define_insn "*xornotdi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ")
- (match_operand:DI 2 "register_operand" "rI"))))]
+(define_insn "*xornot<mode>3"
+ [(set (match_operand:I48MODE 0 "register_operand" "=r")
+ (not:I48MODE (xor:I48MODE
+ (match_operand:I48MODE 1 "register_operand" "%rJ")
+ (match_operand:I48MODE 2 "register_operand" "rI"))))]
""
"eqv %r1,%2,%0"
[(set_attr "type" "ilog")])
@@ -1278,10 +1071,10 @@
(define_expand "ffsdi2"
[(set (match_dup 2)
- (ctz:DI (match_operand:DI 1 "register_operand" "")))
+ (ctz:DI (match_operand:DI 1 "register_operand")))
(set (match_dup 3)
(plus:DI (match_dup 2) (const_int 1)))
- (set (match_operand:DI 0 "register_operand" "")
+ (set (match_operand:DI 0 "register_operand")
(if_then_else:DI (eq (match_dup 1) (const_int 0))
(const_int 0) (match_dup 3)))]
"TARGET_CIX"
@@ -1312,8 +1105,8 @@
[(set_attr "type" "mvi")])
(define_expand "bswapsi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (bswap:SI (match_operand:SI 1 "register_operand" "")))]
+ [(set (match_operand:SI 0 "register_operand")
+ (bswap:SI (match_operand:SI 1 "register_operand")))]
"!optimize_size"
{
rtx t0, t1;
@@ -1334,8 +1127,8 @@
})
(define_expand "bswapdi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (bswap:DI (match_operand:DI 1 "register_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (bswap:DI (match_operand:DI 1 "register_operand")))]
"!optimize_size"
{
rtx t0, t1;
@@ -1418,23 +1211,17 @@
"sra %r1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
- "TARGET_BWX"
- "sextb %1,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
+(define_insn "extendqi<mode>2"
+ [(set (match_operand:I24MODE 0 "register_operand" "=r")
+ (sign_extend:I24MODE
+ (match_operand:QI 1 "register_operand" "r")))]
"TARGET_BWX"
"sextb %1,%0"
[(set_attr "type" "shift")])
(define_expand "extendqidi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (sign_extend:DI (match_operand:QI 1 "some_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (sign_extend:DI (match_operand:QI 1 "some_operand")))]
""
{
if (TARGET_BWX)
@@ -1478,8 +1265,8 @@
[(set_attr "type" "shift")])
(define_expand "extendhidi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (sign_extend:DI (match_operand:HI 1 "some_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (sign_extend:DI (match_operand:HI 1 "some_operand")))]
""
{
if (TARGET_BWX)
@@ -1523,14 +1310,14 @@
(define_expand "unaligned_extendqidi"
[(set (match_dup 3)
- (mem:DI (and:DI (match_operand:DI 1 "address_operand" "") (const_int -8))))
+ (mem:DI (and:DI (match_operand:DI 1 "address_operand") (const_int -8))))
(set (match_dup 4)
(ashift:DI (match_dup 3)
(minus:DI (const_int 64)
(ashift:DI
(and:DI (match_dup 2) (const_int 7))
(const_int 3)))))
- (set (match_operand:QI 0 "register_operand" "")
+ (set (match_operand:QI 0 "register_operand")
(ashiftrt:DI (match_dup 4) (const_int 56)))]
""
{
@@ -1542,14 +1329,14 @@
(define_expand "unaligned_extendhidi"
[(set (match_dup 3)
- (mem:DI (and:DI (match_operand:DI 1 "address_operand" "") (const_int -8))))
+ (mem:DI (and:DI (match_operand:DI 1 "address_operand") (const_int -8))))
(set (match_dup 4)
(ashift:DI (match_dup 3)
(minus:DI (const_int 64)
(ashift:DI
(and:DI (match_dup 2) (const_int 7))
(const_int 3)))))
- (set (match_operand:HI 0 "register_operand" "")
+ (set (match_operand:HI 0 "register_operand")
(ashiftrt:DI (match_dup 4) (const_int 48)))]
""
{
@@ -1570,10 +1357,11 @@
(define_insn "extxl"
[(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
- (match_operand:DI 2 "mode_width_operand" "n")
- (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
- (const_int 3))))]
+ (zero_extract:DI
+ (match_operand:DI 1 "reg_or_0_operand" "rJ")
+ (match_operand:DI 2 "mode_width_operand" "n")
+ (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
+ (const_int 3))))]
""
"ext%M2l %r1,%3,%0"
[(set_attr "type" "shift")])
@@ -1615,11 +1403,11 @@
"extqh %r1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "extlh"
+(define_insn "extwh"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI
(and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
- (const_int 2147483647))
+ (const_int 65535))
(minus:DI (const_int 64)
(ashift:DI
(and:DI
@@ -1627,14 +1415,14 @@
(const_int 7))
(const_int 3)))))]
""
- "extlh %r1,%2,%0"
+ "extwh %r1,%2,%0"
[(set_attr "type" "shift")])
-(define_insn "extwh"
+(define_insn "extlh"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI
(and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
- (const_int 65535))
+ (const_int 2147483647))
(minus:DI (const_int 64)
(ashift:DI
(and:DI
@@ -1642,20 +1430,20 @@
(const_int 7))
(const_int 3)))))]
""
- "extwh %r1,%2,%0"
+ "extlh %r1,%2,%0"
[(set_attr "type" "shift")])
;; This converts an extXl into an extXh with an appropriate adjustment
;; to the address calculation.
;;(define_split
-;; [(set (match_operand:DI 0 "register_operand" "")
-;; (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "")
-;; (match_operand:DI 2 "mode_width_operand" "")
-;; (ashift:DI (match_operand:DI 3 "" "")
+;; [(set (match_operand:DI 0 "register_operand")
+;; (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand")
+;; (match_operand:DI 2 "mode_width_operand")
+;; (ashift:DI (match_operand:DI 3)
;; (const_int 3)))
-;; (match_operand:DI 4 "const_int_operand" "")))
-;; (clobber (match_operand:DI 5 "register_operand" ""))]
+;; (match_operand:DI 4 "const_int_operand")))
+;; (clobber (match_operand:DI 5 "register_operand"))]
;; "INTVAL (operands[4]) == 64 - INTVAL (operands[2])"
;; [(set (match_dup 5) (match_dup 6))
;; (set (match_dup 0)
@@ -1671,55 +1459,23 @@
;; operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
;;}")
-(define_insn "*insbl_const"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
- (match_operand:DI 2 "mul8_operand" "I")))]
- ""
- "insbl %1,%s2,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "inswl_const"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
- (match_operand:DI 2 "mul8_operand" "I")))]
- ""
- "inswl %1,%s2,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "*insll_const"
+(define_insn "ins<modesuffix>l_const"
[(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
+ (ashift:DI (zero_extend:DI
+ (match_operand:I124MODE 1 "register_operand" "r"))
(match_operand:DI 2 "mul8_operand" "I")))]
""
- "insll %1,%s2,%0"
+ "ins<modesuffix>l %1,%s2,%0"
[(set_attr "type" "shift")])
-(define_insn "insbl"
+(define_insn "ins<modesuffix>l"
[(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
+ (ashift:DI (zero_extend:DI
+ (match_operand:I124MODE 1 "register_operand" "r"))
(ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
(const_int 3))))]
""
- "insbl %1,%2,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "inswl"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
- (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
- (const_int 3))))]
- ""
- "inswl %1,%2,%0"
- [(set_attr "type" "shift")])
-
-(define_insn "insll"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
- (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
- (const_int 3))))]
- ""
- "insll %1,%2,%0"
+ "ins<modesuffix>l %1,%2,%0"
[(set_attr "type" "shift")])
(define_insn "insql"
@@ -1825,37 +1581,28 @@
;; from single, so indicate that. The exception are the ones that simply
;; play with the sign bits; it's not clear what to do there.
-(define_insn "abssf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (abs:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "cpys $f31,%R1,%0"
- [(set_attr "type" "fcpys")])
+(define_mode_iterator FMODE [SF DF])
-(define_insn "*nabssf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (neg:SF (abs:SF (match_operand:SF 1 "reg_or_0_operand" "fG"))))]
- "TARGET_FP"
- "cpysn $f31,%R1,%0"
- [(set_attr "type" "fadd")])
+(define_mode_attr opmode [(SF "si") (DF "di")])
-(define_insn "absdf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (abs:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
+(define_insn "abs<mode>2"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (abs:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
"TARGET_FP"
"cpys $f31,%R1,%0"
[(set_attr "type" "fcpys")])
-(define_insn "*nabsdf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (neg:DF (abs:DF (match_operand:DF 1 "reg_or_0_operand" "fG"))))]
+(define_insn "*nabs<mode>2"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (neg:FMODE
+ (abs:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG"))))]
"TARGET_FP"
"cpysn $f31,%R1,%0"
[(set_attr "type" "fadd")])
(define_expand "abstf2"
- [(parallel [(set (match_operand:TF 0 "register_operand" "")
- (abs:TF (match_operand:TF 1 "reg_or_0_operand" "")))
+ [(parallel [(set (match_operand:TF 0 "register_operand")
+ (abs:TF (match_operand:TF 1 "reg_or_0_operand")))
(use (match_dup 2))])]
"TARGET_HAS_XFLOATING_LIBS"
{
@@ -1876,23 +1623,16 @@
[(const_int 0)]
"alpha_split_tfmode_frobsign (operands, gen_andnotdi3); DONE;")
-(define_insn "negsf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (neg:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "cpysn %R1,%R1,%0"
- [(set_attr "type" "fadd")])
-
-(define_insn "negdf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (neg:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
+(define_insn "neg<mode>2"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (neg:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
"TARGET_FP"
"cpysn %R1,%R1,%0"
[(set_attr "type" "fadd")])
(define_expand "negtf2"
- [(parallel [(set (match_operand:TF 0 "register_operand" "")
- (neg:TF (match_operand:TF 1 "reg_or_0_operand" "")))
+ [(parallel [(set (match_operand:TF 0 "register_operand")
+ (neg:TF (match_operand:TF 1 "reg_or_0_operand")))
(use (match_dup 2))])]
"TARGET_HAS_XFLOATING_LIBS"
{
@@ -1913,117 +1653,287 @@
[(const_int 0)]
"alpha_split_tfmode_frobsign (operands, gen_xordi3); DONE;")
-(define_insn "copysignsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")]
- UNSPEC_COPYSIGN))]
+(define_insn "copysign<mode>3"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (unspec:FMODE [(match_operand:FMODE 1 "reg_or_0_operand" "fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")]
+ UNSPEC_COPYSIGN))]
"TARGET_FP"
"cpys %R2,%R1,%0"
[(set_attr "type" "fadd")])
-(define_insn "*ncopysignsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (neg:SF (unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")]
- UNSPEC_COPYSIGN)))]
+(define_insn "*ncopysign<mode>3"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (neg:FMODE
+ (unspec:FMODE [(match_operand:FMODE 1 "reg_or_0_operand" "fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")]
+ UNSPEC_COPYSIGN)))]
"TARGET_FP"
"cpysn %R2,%R1,%0"
[(set_attr "type" "fadd")])
-(define_insn "copysigndf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")]
- UNSPEC_COPYSIGN))]
+(define_insn "*add<mode>3_ieee"
+ [(set (match_operand:FMODE 0 "register_operand" "=&f")
+ (plus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "add<modesuffix>%/ %R1,%R2,%0"
+ [(set_attr "type" "fadd")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_insn "add<mode>3"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (plus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
"TARGET_FP"
- "cpys %R2,%R1,%0"
- [(set_attr "type" "fadd")])
+ "add<modesuffix>%/ %R1,%R2,%0"
+ [(set_attr "type" "fadd")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn "*ncopysigndf3"
+(define_insn "*adddf_ext1"
[(set (match_operand:DF 0 "register_operand" "=f")
- (neg:DF (unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")]
- UNSPEC_COPYSIGN)))]
- "TARGET_FP"
- "cpysn %R2,%R1,%0"
- [(set_attr "type" "fadd")])
+ (plus:DF (float_extend:DF
+ (match_operand:SF 1 "reg_or_0_operand" "fG"))
+ (match_operand:DF 2 "reg_or_0_operand" "fG")))]
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "add%-%/ %R1,%R2,%0"
+ [(set_attr "type" "fadd")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
-(define_insn "*addsf_ieee"
- [(set (match_operand:SF 0 "register_operand" "=&f")
- (plus:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")))]
+(define_insn "*adddf_ext2"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (plus:DF (float_extend:DF
+ (match_operand:SF 1 "reg_or_0_operand" "%fG"))
+ (float_extend:DF
+ (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "add%-%/ %R1,%R2,%0"
+ [(set_attr "type" "fadd")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_expand "addtf3"
+ [(use (match_operand:TF 0 "register_operand"))
+ (use (match_operand:TF 1 "general_operand"))
+ (use (match_operand:TF 2 "general_operand"))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_arith (PLUS, operands); DONE;")
+
+(define_insn "*sub<mode>3_ieee"
+ [(set (match_operand:FMODE 0 "register_operand" "=&f")
+ (minus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
"TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "add%,%/ %R1,%R2,%0"
+ "sub<modesuffix>%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
(set_attr "trap" "yes")
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "u_su_sui")])
-(define_insn "addsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (plus:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")))]
+(define_insn "sub<mode>3"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (minus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
"TARGET_FP"
- "add%,%/ %R1,%R2,%0"
+ "sub<modesuffix>%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
(set_attr "trap" "yes")
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "u_su_sui")])
-(define_insn "*adddf_ieee"
- [(set (match_operand:DF 0 "register_operand" "=&f")
- (plus:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "add%-%/ %R1,%R2,%0"
+(define_insn "*subdf_ext1"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (minus:DF (float_extend:DF
+ (match_operand:SF 1 "reg_or_0_operand" "fG"))
+ (match_operand:DF 2 "reg_or_0_operand" "fG")))]
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "sub%-%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
(set_attr "trap" "yes")
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "u_su_sui")])
-(define_insn "adddf3"
+(define_insn "*subdf_ext2"
[(set (match_operand:DF 0 "register_operand" "=f")
- (plus:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "add%-%/ %R1,%R2,%0"
+ (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
+ (float_extend:DF
+ (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "sub%-%/ %R1,%R2,%0"
[(set_attr "type" "fadd")
(set_attr "trap" "yes")
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "u_su_sui")])
-(define_insn "*adddf_ext1"
+(define_insn "*subdf_ext3"
[(set (match_operand:DF 0 "register_operand" "=f")
- (plus:DF (float_extend:DF
+ (minus:DF (float_extend:DF
+ (match_operand:SF 1 "reg_or_0_operand" "fG"))
+ (float_extend:DF
+ (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "sub%-%/ %R1,%R2,%0"
+ [(set_attr "type" "fadd")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_expand "subtf3"
+ [(use (match_operand:TF 0 "register_operand"))
+ (use (match_operand:TF 1 "general_operand"))
+ (use (match_operand:TF 2 "general_operand"))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_arith (MINUS, operands); DONE;")
+
+(define_insn "*mul<mode>3_ieee"
+ [(set (match_operand:FMODE 0 "register_operand" "=&f")
+ (mult:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "mul<modesuffix>%/ %R1,%R2,%0"
+ [(set_attr "type" "fmul")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_insn "mul<mode>3"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (mult:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
+ "TARGET_FP"
+ "mul<modesuffix>%/ %R1,%R2,%0"
+ [(set_attr "type" "fmul")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_insn "*muldf_ext1"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (mult:DF (float_extend:DF
(match_operand:SF 1 "reg_or_0_operand" "fG"))
(match_operand:DF 2 "reg_or_0_operand" "fG")))]
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "add%-%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
+ "mul%-%/ %R1,%R2,%0"
+ [(set_attr "type" "fmul")
(set_attr "trap" "yes")
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "u_su_sui")])
-(define_insn "*adddf_ext2"
+(define_insn "*muldf_ext2"
[(set (match_operand:DF 0 "register_operand" "=f")
- (plus:DF (float_extend:DF
+ (mult:DF (float_extend:DF
(match_operand:SF 1 "reg_or_0_operand" "%fG"))
(float_extend:DF
(match_operand:SF 2 "reg_or_0_operand" "fG"))))]
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "add%-%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
+ "mul%-%/ %R1,%R2,%0"
+ [(set_attr "type" "fmul")
(set_attr "trap" "yes")
(set_attr "round_suffix" "normal")
(set_attr "trap_suffix" "u_su_sui")])
-(define_expand "addtf3"
- [(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:TF 1 "general_operand" ""))
- (use (match_operand:TF 2 "general_operand" ""))]
+(define_expand "multf3"
+ [(use (match_operand:TF 0 "register_operand"))
+ (use (match_operand:TF 1 "general_operand"))
+ (use (match_operand:TF 2 "general_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
- "alpha_emit_xfloating_arith (PLUS, operands); DONE;")
+ "alpha_emit_xfloating_arith (MULT, operands); DONE;")
+
+(define_insn "*div<mode>3_ieee"
+ [(set (match_operand:FMODE 0 "register_operand" "=&f")
+ (div:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
+ "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
+ "div<modesuffix>%/ %R1,%R2,%0"
+ [(set_attr "type" "fdiv")
+ (set_attr "opsize" "<opmode>")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_insn "div<mode>3"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (div:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
+ (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
+ "TARGET_FP"
+ "div<modesuffix>%/ %R1,%R2,%0"
+ [(set_attr "type" "fdiv")
+ (set_attr "opsize" "<opmode>")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_insn "*divdf_ext1"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))
+ (match_operand:DF 2 "reg_or_0_operand" "fG")))]
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "div%-%/ %R1,%R2,%0"
+ [(set_attr "type" "fdiv")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_insn "*divdf_ext2"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
+ (float_extend:DF
+ (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "div%-%/ %R1,%R2,%0"
+ [(set_attr "type" "fdiv")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_insn "*divdf_ext3"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (div:DF (float_extend:DF
+ (match_operand:SF 1 "reg_or_0_operand" "fG"))
+ (float_extend:DF
+ (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
+ "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
+ "div%-%/ %R1,%R2,%0"
+ [(set_attr "type" "fdiv")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_expand "divtf3"
+ [(use (match_operand:TF 0 "register_operand"))
+ (use (match_operand:TF 1 "general_operand"))
+ (use (match_operand:TF 2 "general_operand"))]
+ "TARGET_HAS_XFLOATING_LIBS"
+ "alpha_emit_xfloating_arith (DIV, operands); DONE;")
+
+(define_insn "*sqrt<mode>2_ieee"
+ [(set (match_operand:FMODE 0 "register_operand" "=&f")
+ (sqrt:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
+ "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
+ "sqrt<modesuffix>%/ %R1,%0"
+ [(set_attr "type" "fsqrt")
+ (set_attr "opsize" "<opmode>")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
+
+(define_insn "sqrt<mode>2"
+ [(set (match_operand:FMODE 0 "register_operand" "=f")
+ (sqrt:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
+ "TARGET_FP && TARGET_FIX"
+ "sqrt<modesuffix>%/ %R1,%0"
+ [(set_attr "type" "fsqrt")
+ (set_attr "opsize" "<opmode>")
+ (set_attr "trap" "yes")
+ (set_attr "round_suffix" "normal")
+ (set_attr "trap_suffix" "u_su_sui")])
;; Define conversion operators between DFmode and SImode, using the cvtql
;; instruction. To allow combine et al to do useful things, we keep the
@@ -2105,16 +2015,14 @@
(set_attr "trap_suffix" "v_sv_svi")])
(define_expand "fix_truncdfdi2"
- [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
- (fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
- "TARGET_FP"
- "")
+ [(set (match_operand:DI 0 "reg_no_subreg_operand")
+ (fix:DI (match_operand:DF 1 "reg_or_0_operand")))]
+ "TARGET_FP")
(define_expand "fixuns_truncdfdi2"
- [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
- (unsigned_fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
- "TARGET_FP"
- "")
+ [(set (match_operand:DI 0 "reg_no_subreg_operand")
+ (unsigned_fix:DI (match_operand:DF 1 "reg_or_0_operand")))]
+ "TARGET_FP")
;; Likewise between SFmode and SImode.
@@ -2132,9 +2040,7 @@
[(set (match_dup 2) (match_op_dup 4 [(float_extend:DF (match_dup 1))]))
(set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
(set (match_dup 5) (match_dup 3))]
-{
- operands[5] = adjust_address (operands[0], SFmode, 0);
-}
+ "operands[5] = adjust_address (operands[0], SFmode, 0);"
[(set_attr "type" "fadd")
(set_attr "trap" "yes")])
@@ -2181,27 +2087,25 @@
(set_attr "trap_suffix" "v_sv_svi")])
(define_expand "fix_truncsfdi2"
- [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
- (fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
- "TARGET_FP"
- "")
+ [(set (match_operand:DI 0 "reg_no_subreg_operand")
+ (fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))))]
+ "TARGET_FP")
(define_expand "fixuns_truncsfdi2"
- [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
+ [(set (match_operand:DI 0 "reg_no_subreg_operand")
(unsigned_fix:DI
- (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
- "TARGET_FP"
- "")
+ (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))))]
+ "TARGET_FP")
(define_expand "fix_trunctfdi2"
- [(use (match_operand:DI 0 "register_operand" ""))
- (use (match_operand:TF 1 "general_operand" ""))]
+ [(use (match_operand:DI 0 "register_operand"))
+ (use (match_operand:TF 1 "general_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_cvt (FIX, operands); DONE;")
(define_expand "fixuns_trunctfdi2"
- [(use (match_operand:DI 0 "register_operand" ""))
- (use (match_operand:TF 1 "general_operand" ""))]
+ [(use (match_operand:DI 0 "register_operand"))
+ (use (match_operand:TF 1 "general_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_cvt (UNSIGNED_FIX, operands); DONE;")
@@ -2236,9 +2140,7 @@
[(set (match_dup 3) (match_dup 1))
(set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
(set (match_dup 0) (float:SF (match_dup 2)))]
-{
- operands[1] = adjust_address (operands[1], SFmode, 0);
-})
+ "operands[1] = adjust_address (operands[1], SFmode, 0);")
(define_insn_and_split "*floatsisf2"
[(set (match_operand:SF 0 "register_operand" "=f")
@@ -2285,9 +2187,7 @@
[(set (match_dup 3) (match_dup 1))
(set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
(set (match_dup 0) (float:DF (match_dup 2)))]
-{
- operands[1] = adjust_address (operands[1], SFmode, 0);
-})
+ "operands[1] = adjust_address (operands[1], SFmode, 0);")
(define_insn_and_split "*floatsidf2"
[(set (match_operand:DF 0 "register_operand" "=f")
@@ -2305,32 +2205,32 @@
})
(define_expand "floatditf2"
- [(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:DI 1 "general_operand" ""))]
+ [(use (match_operand:TF 0 "register_operand"))
+ (use (match_operand:DI 1 "general_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_cvt (FLOAT, operands); DONE;")
(define_expand "floatunsdisf2"
- [(use (match_operand:SF 0 "register_operand" ""))
- (use (match_operand:DI 1 "register_operand" ""))]
+ [(use (match_operand:SF 0 "register_operand"))
+ (use (match_operand:DI 1 "register_operand"))]
"TARGET_FP"
"alpha_emit_floatuns (operands); DONE;")
(define_expand "floatunsdidf2"
- [(use (match_operand:DF 0 "register_operand" ""))
- (use (match_operand:DI 1 "register_operand" ""))]
+ [(use (match_operand:DF 0 "register_operand"))
+ (use (match_operand:DI 1 "register_operand"))]
"TARGET_FP"
"alpha_emit_floatuns (operands); DONE;")
(define_expand "floatunsditf2"
- [(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:DI 1 "general_operand" ""))]
+ [(use (match_operand:TF 0 "register_operand"))
+ (use (match_operand:DI 1 "general_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_cvt (UNSIGNED_FLOAT, operands); DONE;")
(define_expand "extendsfdf2"
- [(set (match_operand:DF 0 "register_operand" "")
- (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
+ [(set (match_operand:DF 0 "register_operand")
+ (float_extend:DF (match_operand:SF 1 "nonimmediate_operand")))]
"TARGET_FP"
{
if (alpha_fptm >= ALPHA_FPTM_SU)
@@ -2362,8 +2262,8 @@
;; from doing something silly. When optimizing we'll put things back
;; together anyway.
(define_expand "extendsftf2"
- [(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:SF 1 "register_operand" ""))]
+ [(use (match_operand:TF 0 "register_operand"))
+ (use (match_operand:SF 1 "register_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
{
rtx tmp = gen_reg_rtx (DFmode);
@@ -2373,8 +2273,8 @@
})
(define_expand "extenddftf2"
- [(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:DF 1 "register_operand" ""))]
+ [(use (match_operand:TF 0 "register_operand"))
+ (use (match_operand:DF 1 "register_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;")
@@ -2399,14 +2299,14 @@
(set_attr "trap_suffix" "u_su_sui")])
(define_expand "trunctfdf2"
- [(use (match_operand:DF 0 "register_operand" ""))
- (use (match_operand:TF 1 "general_operand" ""))]
+ [(use (match_operand:DF 0 "register_operand"))
+ (use (match_operand:TF 1 "general_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
"alpha_emit_xfloating_cvt (FLOAT_TRUNCATE, operands); DONE;")
(define_expand "trunctfsf2"
- [(use (match_operand:SF 0 "register_operand" ""))
- (use (match_operand:TF 1 "general_operand" ""))]
+ [(use (match_operand:SF 0 "register_operand"))
+ (use (match_operand:TF 1 "general_operand"))]
"TARGET_FP && TARGET_HAS_XFLOATING_LIBS"
{
rtx tmpf, sticky, arg, lo, hi;
@@ -2429,299 +2329,6 @@
emit_insn (gen_truncdfsf2 (operands[0], tmpf));
DONE;
})
-
-(define_insn "*divsf3_ieee"
- [(set (match_operand:SF 0 "register_operand" "=&f")
- (div:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "div%,%/ %R1,%R2,%0"
- [(set_attr "type" "fdiv")
- (set_attr "opsize" "si")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "divsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (div:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "div%,%/ %R1,%R2,%0"
- [(set_attr "type" "fdiv")
- (set_attr "opsize" "si")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*divdf3_ieee"
- [(set (match_operand:DF 0 "register_operand" "=&f")
- (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "div%-%/ %R1,%R2,%0"
- [(set_attr "type" "fdiv")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "divdf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "div%-%/ %R1,%R2,%0"
- [(set_attr "type" "fdiv")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*divdf_ext1"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "div%-%/ %R1,%R2,%0"
- [(set_attr "type" "fdiv")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*divdf_ext2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
- (float_extend:DF
- (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
- "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "div%-%/ %R1,%R2,%0"
- [(set_attr "type" "fdiv")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*divdf_ext3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))
- (float_extend:DF (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
- "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "div%-%/ %R1,%R2,%0"
- [(set_attr "type" "fdiv")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_expand "divtf3"
- [(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:TF 1 "general_operand" ""))
- (use (match_operand:TF 2 "general_operand" ""))]
- "TARGET_HAS_XFLOATING_LIBS"
- "alpha_emit_xfloating_arith (DIV, operands); DONE;")
-
-(define_insn "*mulsf3_ieee"
- [(set (match_operand:SF 0 "register_operand" "=&f")
- (mult:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "mul%,%/ %R1,%R2,%0"
- [(set_attr "type" "fmul")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "mulsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (mult:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "mul%,%/ %R1,%R2,%0"
- [(set_attr "type" "fmul")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*muldf3_ieee"
- [(set (match_operand:DF 0 "register_operand" "=&f")
- (mult:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "mul%-%/ %R1,%R2,%0"
- [(set_attr "type" "fmul")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "muldf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (mult:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "mul%-%/ %R1,%R2,%0"
- [(set_attr "type" "fmul")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*muldf_ext1"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (mult:DF (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "mul%-%/ %R1,%R2,%0"
- [(set_attr "type" "fmul")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*muldf_ext2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (mult:DF (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "%fG"))
- (float_extend:DF
- (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
- "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "mul%-%/ %R1,%R2,%0"
- [(set_attr "type" "fmul")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_expand "multf3"
- [(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:TF 1 "general_operand" ""))
- (use (match_operand:TF 2 "general_operand" ""))]
- "TARGET_HAS_XFLOATING_LIBS"
- "alpha_emit_xfloating_arith (MULT, operands); DONE;")
-
-(define_insn "*subsf3_ieee"
- [(set (match_operand:SF 0 "register_operand" "=&f")
- (minus:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "sub%,%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "subsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (minus:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
- (match_operand:SF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "sub%,%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*subdf3_ieee"
- [(set (match_operand:DF 0 "register_operand" "=&f")
- (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
- "sub%-%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "subdf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP"
- "sub%-%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*subdf_ext1"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (minus:DF (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))
- (match_operand:DF 2 "reg_or_0_operand" "fG")))]
- "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "sub%-%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*subdf_ext2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
- (float_extend:DF
- (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
- "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "sub%-%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*subdf_ext3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (minus:DF (float_extend:DF
- (match_operand:SF 1 "reg_or_0_operand" "fG"))
- (float_extend:DF
- (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
- "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
- "sub%-%/ %R1,%R2,%0"
- [(set_attr "type" "fadd")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_expand "subtf3"
- [(use (match_operand:TF 0 "register_operand" ""))
- (use (match_operand:TF 1 "general_operand" ""))
- (use (match_operand:TF 2 "general_operand" ""))]
- "TARGET_HAS_XFLOATING_LIBS"
- "alpha_emit_xfloating_arith (MINUS, operands); DONE;")
-
-(define_insn "*sqrtsf2_ieee"
- [(set (match_operand:SF 0 "register_operand" "=&f")
- (sqrt:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
- "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
- "sqrt%,%/ %R1,%0"
- [(set_attr "type" "fsqrt")
- (set_attr "opsize" "si")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "sqrtsf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (sqrt:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
- "TARGET_FP && TARGET_FIX"
- "sqrt%,%/ %R1,%0"
- [(set_attr "type" "fsqrt")
- (set_attr "opsize" "si")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "*sqrtdf2_ieee"
- [(set (match_operand:DF 0 "register_operand" "=&f")
- (sqrt:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
- "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
- "sqrt%-%/ %R1,%0"
- [(set_attr "type" "fsqrt")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
-
-(define_insn "sqrtdf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (sqrt:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
- "TARGET_FP && TARGET_FIX"
- "sqrt%-%/ %R1,%0"
- [(set_attr "type" "fsqrt")
- (set_attr "trap" "yes")
- (set_attr "round_suffix" "normal")
- (set_attr "trap_suffix" "u_su_sui")])
;; Next are all the integer comparisons, and conditional moves and branches
;; and some of the related define_expand's and define_split's.
@@ -2772,14 +2379,14 @@
;; in order to create more pairs of constants. As long as we're allowing
;; two constants at the same time, and will have to reload one of them...
-(define_insn "*movqicc_internal"
- [(set (match_operand:QI 0 "register_operand" "=r,r,r,r")
- (if_then_else:QI
+(define_insn "*mov<mode>cc_internal"
+ [(set (match_operand:IMODE 0 "register_operand" "=r,r,r,r")
+ (if_then_else:IMODE
(match_operator 2 "signed_comparison_operator"
[(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
(match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
- (match_operand:QI 1 "add_operand" "rI,0,rI,0")
- (match_operand:QI 5 "add_operand" "0,rI,0,rI")))]
+ (match_operand:IMODE 1 "add_operand" "rI,0,rI,0")
+ (match_operand:IMODE 5 "add_operand" "0,rI,0,rI")))]
"(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
"@
cmov%C2 %r3,%1,%0
@@ -2788,168 +2395,30 @@
cmov%d2 %r4,%5,%0"
[(set_attr "type" "icmov")])
-(define_insn "*movhicc_internal"
- [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
- (if_then_else:HI
- (match_operator 2 "signed_comparison_operator"
- [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
- (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
- (match_operand:HI 1 "add_operand" "rI,0,rI,0")
- (match_operand:HI 5 "add_operand" "0,rI,0,rI")))]
- "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
- "@
- cmov%C2 %r3,%1,%0
- cmov%D2 %r3,%5,%0
- cmov%c2 %r4,%1,%0
- cmov%d2 %r4,%5,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movsicc_internal"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
- (if_then_else:SI
- (match_operator 2 "signed_comparison_operator"
- [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
- (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
- (match_operand:SI 1 "add_operand" "rI,0,rI,0")
- (match_operand:SI 5 "add_operand" "0,rI,0,rI")))]
- "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
- "@
- cmov%C2 %r3,%1,%0
- cmov%D2 %r3,%5,%0
- cmov%c2 %r4,%1,%0
- cmov%d2 %r4,%5,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movdicc_internal"
- [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
- (if_then_else:DI
- (match_operator 2 "signed_comparison_operator"
- [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
- (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
- (match_operand:DI 1 "add_operand" "rI,0,rI,0")
- (match_operand:DI 5 "add_operand" "0,rI,0,rI")))]
- "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
- "@
- cmov%C2 %r3,%1,%0
- cmov%D2 %r3,%5,%0
- cmov%c2 %r4,%1,%0
- cmov%d2 %r4,%5,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movqicc_lbc"
- [(set (match_operand:QI 0 "register_operand" "=r,r")
- (if_then_else:QI
- (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
- (const_int 1)
- (const_int 0))
- (const_int 0))
- (match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
- (match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
- ""
- "@
- cmovlbc %r2,%1,%0
- cmovlbs %r2,%3,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movhicc_lbc"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (if_then_else:HI
+(define_insn "*mov<mode>cc_lbc"
+ [(set (match_operand:IMODE 0 "register_operand" "=r,r")
+ (if_then_else:IMODE
(eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
(const_int 1)
(const_int 0))
(const_int 0))
- (match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
- (match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
+ (match_operand:IMODE 1 "reg_or_8bit_operand" "rI,0")
+ (match_operand:IMODE 3 "reg_or_8bit_operand" "0,rI")))]
""
"@
cmovlbc %r2,%1,%0
cmovlbs %r2,%3,%0"
[(set_attr "type" "icmov")])
-(define_insn "*movsicc_lbc"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (if_then_else:SI
- (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
- (const_int 1)
- (const_int 0))
- (const_int 0))
- (match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
- (match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
- ""
- "@
- cmovlbc %r2,%1,%0
- cmovlbs %r2,%3,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movdicc_lbc"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (if_then_else:DI
- (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
- (const_int 1)
- (const_int 0))
- (const_int 0))
- (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
- (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
- ""
- "@
- cmovlbc %r2,%1,%0
- cmovlbs %r2,%3,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movqicc_lbs"
- [(set (match_operand:QI 0 "register_operand" "=r,r")
- (if_then_else:QI
- (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
- (const_int 1)
- (const_int 0))
- (const_int 0))
- (match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
- (match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
- ""
- "@
- cmovlbs %r2,%1,%0
- cmovlbc %r2,%3,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movhicc_lbs"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (if_then_else:HI
- (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
- (const_int 1)
- (const_int 0))
- (const_int 0))
- (match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
- (match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
- ""
- "@
- cmovlbs %r2,%1,%0
- cmovlbc %r2,%3,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movsicc_lbs"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (if_then_else:SI
- (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
- (const_int 1)
- (const_int 0))
- (const_int 0))
- (match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
- (match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
- ""
- "@
- cmovlbs %r2,%1,%0
- cmovlbc %r2,%3,%0"
- [(set_attr "type" "icmov")])
-
-(define_insn "*movdicc_lbs"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (if_then_else:DI
+(define_insn "*mov<mode>cc_lbs"
+ [(set (match_operand:IMODE 0 "register_operand" "=r,r")
+ (if_then_else:IMODE
(ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
(const_int 1)
(const_int 0))
(const_int 0))
- (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
- (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
+ (match_operand:IMODE 1 "reg_or_8bit_operand" "rI,0")
+ (match_operand:IMODE 3 "reg_or_8bit_operand" "0,rI")))]
""
"@
cmovlbs %r2,%1,%0
@@ -2959,8 +2428,8 @@
;; For ABS, we have two choices, depending on whether the input and output
;; registers are the same or not.
(define_expand "absdi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (abs:DI (match_operand:DI 1 "register_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (abs:DI (match_operand:DI 1 "register_operand")))]
""
{
if (rtx_equal_p (operands[0], operands[1]))
@@ -2971,147 +2440,83 @@
})
(define_expand "absdi2_same"
- [(set (match_operand:DI 1 "register_operand" "")
- (neg:DI (match_operand:DI 0 "register_operand" "")))
+ [(set (match_operand:DI 1 "register_operand")
+ (neg:DI (match_operand:DI 0 "register_operand")))
(set (match_dup 0)
(if_then_else:DI (ge (match_dup 0) (const_int 0))
(match_dup 0)
- (match_dup 1)))]
- ""
- "")
+ (match_dup 1)))])
(define_expand "absdi2_diff"
- [(set (match_operand:DI 0 "register_operand" "")
- (neg:DI (match_operand:DI 1 "register_operand" "")))
+ [(set (match_operand:DI 0 "register_operand")
+ (neg:DI (match_operand:DI 1 "register_operand")))
(set (match_dup 0)
(if_then_else:DI (lt (match_dup 1) (const_int 0))
(match_dup 0)
- (match_dup 1)))]
- ""
- "")
+ (match_dup 1)))])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(abs:DI (match_dup 0)))
- (clobber (match_operand:DI 1 "register_operand" ""))]
+ (clobber (match_operand:DI 1 "register_operand"))]
""
[(set (match_dup 1) (neg:DI (match_dup 0)))
(set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
- (match_dup 0) (match_dup 1)))]
- "")
+ (match_dup 0) (match_dup 1)))])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (abs:DI (match_operand:DI 1 "register_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (abs:DI (match_operand:DI 1 "register_operand")))]
"! rtx_equal_p (operands[0], operands[1])"
[(set (match_dup 0) (neg:DI (match_dup 1)))
(set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
- (match_dup 0) (match_dup 1)))]
- "")
+ (match_dup 0) (match_dup 1)))])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(neg:DI (abs:DI (match_dup 0))))
- (clobber (match_operand:DI 1 "register_operand" ""))]
+ (clobber (match_operand:DI 1 "register_operand"))]
""
[(set (match_dup 1) (neg:DI (match_dup 0)))
(set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
- (match_dup 0) (match_dup 1)))]
- "")
+ (match_dup 0) (match_dup 1)))])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))]
+ [(set (match_operand:DI 0 "register_operand")
+ (neg:DI (abs:DI (match_operand:DI 1 "register_operand"))))]
"! rtx_equal_p (operands[0], operands[1])"
[(set (match_dup 0) (neg:DI (match_dup 1)))
(set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
- (match_dup 0) (match_dup 1)))]
- "")
-
-(define_insn "sminqi3"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (smin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
- (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
- "TARGET_MAX"
- "minsb8 %r1,%2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "uminqi3"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (umin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
- (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
- "TARGET_MAX"
- "minub8 %r1,%2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "smaxqi3"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (smax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
- (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
- "TARGET_MAX"
- "maxsb8 %r1,%2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "umaxqi3"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (umax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
- (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
- "TARGET_MAX"
- "maxub8 %r1,%2,%0"
- [(set_attr "type" "mvi")])
+ (match_dup 0) (match_dup 1)))])
-(define_insn "sminhi3"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (smin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
- (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
- "TARGET_MAX"
- "minsw4 %r1,%2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "uminhi3"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (umin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
- (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
- "TARGET_MAX"
- "minuw4 %r1,%2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "smaxhi3"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (smax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
- (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
- "TARGET_MAX"
- "maxsw4 %r1,%2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "umaxhi3"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (umax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
- (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
+(define_insn "<code><mode>3"
+ [(set (match_operand:I12MODE 0 "register_operand" "=r")
+ (any_maxmin:I12MODE
+ (match_operand:I12MODE 1 "reg_or_0_operand" "%rJ")
+ (match_operand:I12MODE 2 "reg_or_8bit_operand" "rI")))]
"TARGET_MAX"
- "maxuw4 %r1,%2,%0"
+ "<maxmin><vecmodesuffix> %r1,%2,%0"
[(set_attr "type" "mvi")])
(define_expand "smaxdi3"
[(set (match_dup 3)
- (le:DI (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")))
- (set (match_operand:DI 0 "register_operand" "")
+ (le:DI (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")))
+ (set (match_operand:DI 0 "register_operand")
(if_then_else:DI (eq (match_dup 3) (const_int 0))
(match_dup 1) (match_dup 2)))]
""
- { operands[3] = gen_reg_rtx (DImode); })
+ "operands[3] = gen_reg_rtx (DImode);")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (smax:DI (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")))
- (clobber (match_operand:DI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (smax:DI (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")))
+ (clobber (match_operand:DI 3 "register_operand"))]
"operands[2] != const0_rtx"
[(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
(set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
- (match_dup 1) (match_dup 2)))]
- "")
+ (match_dup 1) (match_dup 2)))])
(define_insn "*smax_const0"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -3123,24 +2528,23 @@
(define_expand "smindi3"
[(set (match_dup 3)
- (lt:DI (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")))
- (set (match_operand:DI 0 "register_operand" "")
+ (lt:DI (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")))
+ (set (match_operand:DI 0 "register_operand")
(if_then_else:DI (ne (match_dup 3) (const_int 0))
(match_dup 1) (match_dup 2)))]
""
- { operands[3] = gen_reg_rtx (DImode); })
+ "operands[3] = gen_reg_rtx (DImode);")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (smin:DI (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")))
- (clobber (match_operand:DI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (smin:DI (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")))
+ (clobber (match_operand:DI 3 "register_operand"))]
"operands[2] != const0_rtx"
[(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
(set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
- (match_dup 1) (match_dup 2)))]
- "")
+ (match_dup 1) (match_dup 2)))])
(define_insn "*smin_const0"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -3152,45 +2556,43 @@
(define_expand "umaxdi3"
[(set (match_dup 3)
- (leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")))
- (set (match_operand:DI 0 "register_operand" "")
+ (leu:DI (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")))
+ (set (match_operand:DI 0 "register_operand")
(if_then_else:DI (eq (match_dup 3) (const_int 0))
(match_dup 1) (match_dup 2)))]
""
"operands[3] = gen_reg_rtx (DImode);")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (umax:DI (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")))
- (clobber (match_operand:DI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (umax:DI (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")))
+ (clobber (match_operand:DI 3 "register_operand"))]
"operands[2] != const0_rtx"
[(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
(set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
- (match_dup 1) (match_dup 2)))]
- "")
+ (match_dup 1) (match_dup 2)))])
(define_expand "umindi3"
[(set (match_dup 3)
- (ltu:DI (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")))
- (set (match_operand:DI 0 "register_operand" "")
+ (ltu:DI (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")))
+ (set (match_operand:DI 0 "register_operand")
(if_then_else:DI (ne (match_dup 3) (const_int 0))
(match_dup 1) (match_dup 2)))]
""
"operands[3] = gen_reg_rtx (DImode);")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (umin:DI (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")))
- (clobber (match_operand:DI 3 "register_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (umin:DI (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")))
+ (clobber (match_operand:DI 3 "register_operand"))]
"operands[2] != const0_rtx"
[(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
(set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
- (match_dup 1) (match_dup 2)))]
- "")
+ (match_dup 1) (match_dup 2)))])
(define_insn "*bcc_normal"
[(set (pc)
@@ -3198,7 +2600,7 @@
(match_operator 1 "signed_comparison_operator"
[(match_operand:DI 2 "reg_or_0_operand" "rJ")
(const_int 0)])
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0))
(pc)))]
""
"b%C1 %r2,%0"
@@ -3212,7 +2614,7 @@
(const_int 0)])
(pc)
- (label_ref (match_operand 0 "" ""))))]
+ (label_ref (match_operand 0))))]
""
"b%c1 %2,%0"
[(set_attr "type" "ibr")])
@@ -3224,7 +2626,7 @@
(const_int 1)
(const_int 0))
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0))
(pc)))]
""
"blbs %r1,%0"
@@ -3237,7 +2639,7 @@
(const_int 1)
(const_int 0))
(const_int 0))
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0))
(pc)))]
""
"blbc %r1,%0"
@@ -3248,13 +2650,13 @@
[(set (pc)
(if_then_else
(match_operator 1 "comparison_operator"
- [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
- (const_int 1)
- (match_operand:DI 3 "const_int_operand" ""))
- (const_int 0)])
- (label_ref (match_operand 0 "" ""))
+ [(zero_extract:DI (match_operand:DI 2 "register_operand")
+ (const_int 1)
+ (match_operand:DI 3 "const_int_operand"))
+ (const_int 0)])
+ (label_ref (match_operand 0))
(pc)))
- (clobber (match_operand:DI 4 "register_operand" ""))])]
+ (clobber (match_operand:DI 4 "register_operand"))])]
"INTVAL (operands[3]) != 0"
[(set (match_dup 4)
(lshiftrt:DI (match_dup 2) (match_dup 3)))
@@ -3266,7 +2668,7 @@
(const_int 0)])
(label_ref (match_dup 0))
(pc)))]
- "")
+ )
;; The following are the corresponding floating-point insns. Recall
;; we need to have variants that expand the arguments from SFmode
@@ -3331,28 +2733,14 @@
(set_attr "trap" "yes")
(set_attr "trap_suffix" "su")])
-(define_insn "*movdfcc_internal"
- [(set (match_operand:DF 0 "register_operand" "=f,f")
- (if_then_else:DF
- (match_operator 3 "signed_comparison_operator"
- [(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
- (match_operand:DF 2 "const0_operand" "G,G")])
- (match_operand:DF 1 "reg_or_0_operand" "fG,0")
- (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
- "TARGET_FP"
- "@
- fcmov%C3 %R4,%R1,%0
- fcmov%D3 %R4,%R5,%0"
- [(set_attr "type" "fcmov")])
-
-(define_insn "*movsfcc_internal"
- [(set (match_operand:SF 0 "register_operand" "=f,f")
- (if_then_else:SF
+(define_insn "*mov<mode>cc_internal"
+ [(set (match_operand:FMODE 0 "register_operand" "=f,f")
+ (if_then_else:FMODE
(match_operator 3 "signed_comparison_operator"
[(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
(match_operand:DF 2 "const0_operand" "G,G")])
- (match_operand:SF 1 "reg_or_0_operand" "fG,0")
- (match_operand:SF 5 "reg_or_0_operand" "0,fG")))]
+ (match_operand:FMODE 1 "reg_or_0_operand" "fG,0")
+ (match_operand:FMODE 5 "reg_or_0_operand" "0,fG")))]
"TARGET_FP"
"@
fcmov%C3 %R4,%R1,%0
@@ -3420,9 +2808,9 @@
(define_expand "smaxdf3"
[(set (match_dup 3)
- (le:DF (match_operand:DF 1 "reg_or_0_operand" "")
- (match_operand:DF 2 "reg_or_0_operand" "")))
- (set (match_operand:DF 0 "register_operand" "")
+ (le:DF (match_operand:DF 1 "reg_or_0_operand")
+ (match_operand:DF 2 "reg_or_0_operand")))
+ (set (match_operand:DF 0 "register_operand")
(if_then_else:DF (eq (match_dup 3) (match_dup 4))
(match_dup 1) (match_dup 2)))]
"TARGET_FP"
@@ -3433,9 +2821,9 @@
(define_expand "smindf3"
[(set (match_dup 3)
- (lt:DF (match_operand:DF 1 "reg_or_0_operand" "")
- (match_operand:DF 2 "reg_or_0_operand" "")))
- (set (match_operand:DF 0 "register_operand" "")
+ (lt:DF (match_operand:DF 1 "reg_or_0_operand")
+ (match_operand:DF 2 "reg_or_0_operand")))
+ (set (match_operand:DF 0 "register_operand")
(if_then_else:DF (ne (match_dup 3) (match_dup 4))
(match_dup 1) (match_dup 2)))]
"TARGET_FP"
@@ -3446,9 +2834,9 @@
(define_expand "smaxsf3"
[(set (match_dup 3)
- (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))
- (float_extend:DF (match_operand:SF 2 "reg_or_0_operand" ""))))
- (set (match_operand:SF 0 "register_operand" "")
+ (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))
+ (float_extend:DF (match_operand:SF 2 "reg_or_0_operand"))))
+ (set (match_operand:SF 0 "register_operand")
(if_then_else:SF (eq (match_dup 3) (match_dup 4))
(match_dup 1) (match_dup 2)))]
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
@@ -3459,9 +2847,9 @@
(define_expand "sminsf3"
[(set (match_dup 3)
- (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))
- (float_extend:DF (match_operand:SF 2 "reg_or_0_operand" ""))))
- (set (match_operand:SF 0 "register_operand" "")
+ (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))
+ (float_extend:DF (match_operand:SF 2 "reg_or_0_operand"))))
+ (set (match_operand:SF 0 "register_operand")
(if_then_else:SF (ne (match_dup 3) (match_dup 4))
(match_dup 1) (match_dup 2)))]
"TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
@@ -3476,7 +2864,7 @@
(match_operator 1 "signed_comparison_operator"
[(match_operand:DF 2 "reg_or_0_operand" "fG")
(match_operand:DF 3 "const0_operand" "G")])
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0))
(pc)))]
"TARGET_FP"
"fb%C1 %R2,%0"
@@ -3489,7 +2877,7 @@
[(float_extend:DF
(match_operand:SF 2 "reg_or_0_operand" "fG"))
(match_operand:DF 3 "const0_operand" "G")])
- (label_ref (match_operand 0 "" ""))
+ (label_ref (match_operand 0))
(pc)))]
"TARGET_FP"
"fb%C1 %R2,%0"
@@ -3500,27 +2888,27 @@
(define_expand "cbranchdf4"
[(use (match_operator 0 "alpha_cbranch_operator"
- [(match_operand:DF 1 "reg_or_0_operand" "")
- (match_operand:DF 2 "reg_or_0_operand" "")]))
- (use (match_operand 3 ""))]
+ [(match_operand:DF 1 "reg_or_0_operand")
+ (match_operand:DF 2 "reg_or_0_operand")]))
+ (use (match_operand 3))]
"TARGET_FP"
- { alpha_emit_conditional_branch (operands, DFmode); DONE; })
+ "alpha_emit_conditional_branch (operands, DFmode); DONE;")
(define_expand "cbranchtf4"
[(use (match_operator 0 "alpha_cbranch_operator"
[(match_operand:TF 1 "general_operand")
(match_operand:TF 2 "general_operand")]))
- (use (match_operand 3 ""))]
+ (use (match_operand 3))]
"TARGET_HAS_XFLOATING_LIBS"
- { alpha_emit_conditional_branch (operands, TFmode); DONE; })
+ "alpha_emit_conditional_branch (operands, TFmode); DONE;")
(define_expand "cbranchdi4"
[(use (match_operator 0 "alpha_cbranch_operator"
[(match_operand:DI 1 "some_operand")
(match_operand:DI 2 "some_operand")]))
- (use (match_operand 3 ""))]
+ (use (match_operand 3))]
""
- { alpha_emit_conditional_branch (operands, DImode); DONE; })
+ "alpha_emit_conditional_branch (operands, DImode); DONE;")
(define_expand "cstoredf4"
[(use (match_operator:DI 1 "alpha_cbranch_operator"
@@ -3528,7 +2916,12 @@
(match_operand:DF 3 "reg_or_0_operand")]))
(clobber (match_operand:DI 0 "register_operand"))]
"TARGET_FP"
- { if (!alpha_emit_setcc (operands, DFmode)) FAIL; else DONE; })
+{
+ if (alpha_emit_setcc (operands, DFmode))
+ DONE;
+ else
+ FAIL;
+})
(define_expand "cstoretf4"
[(use (match_operator:DI 1 "alpha_cbranch_operator"
@@ -3536,7 +2929,12 @@
(match_operand:TF 3 "general_operand")]))
(clobber (match_operand:DI 0 "register_operand"))]
"TARGET_HAS_XFLOATING_LIBS"
- { if (!alpha_emit_setcc (operands, TFmode)) FAIL; else DONE; })
+{
+ if (alpha_emit_setcc (operands, TFmode))
+ DONE;
+ else
+ FAIL;
+})
(define_expand "cstoredi4"
[(use (match_operator:DI 1 "alpha_cbranch_operator"
@@ -3544,51 +2942,38 @@
(match_operand:DI 3 "some_operand")]))
(clobber (match_operand:DI 0 "register_operand"))]
""
- { if (!alpha_emit_setcc (operands, DImode)) FAIL; else DONE; })
-
-;; These are the main define_expand's used to make conditional moves.
-
-(define_expand "movsicc"
- [(set (match_operand:SI 0 "register_operand" "")
- (if_then_else:SI (match_operand 1 "comparison_operator" "")
- (match_operand:SI 2 "reg_or_8bit_operand" "")
- (match_operand:SI 3 "reg_or_8bit_operand" "")))]
- ""
-{
- if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0)
- FAIL;
-})
-
-(define_expand "movdicc"
- [(set (match_operand:DI 0 "register_operand" "")
- (if_then_else:DI (match_operand 1 "comparison_operator" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")
- (match_operand:DI 3 "reg_or_8bit_operand" "")))]
- ""
{
- if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0)
+ if (alpha_emit_setcc (operands, DImode))
+ DONE;
+ else
FAIL;
})
+
+;; These are the main define_expand's used to make conditional moves.
-(define_expand "movsfcc"
- [(set (match_operand:SF 0 "register_operand" "")
- (if_then_else:SF (match_operand 1 "comparison_operator" "")
- (match_operand:SF 2 "reg_or_8bit_operand" "")
- (match_operand:SF 3 "reg_or_8bit_operand" "")))]
+(define_expand "mov<mode>cc"
+ [(set (match_operand:I48MODE 0 "register_operand")
+ (if_then_else:I48MODE
+ (match_operand 1 "comparison_operator")
+ (match_operand:I48MODE 2 "reg_or_8bit_operand")
+ (match_operand:I48MODE 3 "reg_or_8bit_operand")))]
""
{
- if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0)
+ operands[1] = alpha_emit_conditional_move (operands[1], <MODE>mode);
+ if (operands[1] == 0)
FAIL;
})
-(define_expand "movdfcc"
- [(set (match_operand:DF 0 "register_operand" "")
- (if_then_else:DF (match_operand 1 "comparison_operator" "")
- (match_operand:DF 2 "reg_or_8bit_operand" "")
- (match_operand:DF 3 "reg_or_8bit_operand" "")))]
+(define_expand "mov<mode>cc"
+ [(set (match_operand:FMODE 0 "register_operand")
+ (if_then_else:FMODE
+ (match_operand 1 "comparison_operator")
+ (match_operand:FMODE 2 "reg_or_8bit_operand")
+ (match_operand:FMODE 3 "reg_or_8bit_operand")))]
""
{
- if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0)
+ operands[1] = alpha_emit_conditional_move (operands[1], <MODE>mode);
+ if (operands[1] == 0)
FAIL;
})
@@ -3610,14 +2995,14 @@
;; operation could have been generated.
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(if_then_else:DI
(match_operator 1 "comparison_operator"
- [(match_operand:DI 2 "reg_or_0_operand" "")
- (match_operand:DI 3 "reg_or_cint_operand" "")])
- (match_operand:DI 4 "reg_or_cint_operand" "")
- (match_operand:DI 5 "reg_or_cint_operand" "")))
- (clobber (match_operand:DI 6 "register_operand" ""))]
+ [(match_operand:DI 2 "reg_or_0_operand")
+ (match_operand:DI 3 "reg_or_cint_operand")])
+ (match_operand:DI 4 "reg_or_cint_operand")
+ (match_operand:DI 5 "reg_or_cint_operand")))
+ (clobber (match_operand:DI 6 "register_operand"))]
"operands[3] != const0_rtx"
[(set (match_dup 6) (match_dup 7))
(set (match_dup 0)
@@ -3667,14 +3052,14 @@
})
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(if_then_else:DI
(match_operator 1 "comparison_operator"
- [(match_operand:SI 2 "reg_or_0_operand" "")
- (match_operand:SI 3 "reg_or_cint_operand" "")])
- (match_operand:DI 4 "reg_or_8bit_operand" "")
- (match_operand:DI 5 "reg_or_8bit_operand" "")))
- (clobber (match_operand:DI 6 "register_operand" ""))]
+ [(match_operand:SI 2 "reg_or_0_operand")
+ (match_operand:SI 3 "reg_or_cint_operand")])
+ (match_operand:DI 4 "reg_or_8bit_operand")
+ (match_operand:DI 5 "reg_or_8bit_operand")))
+ (clobber (match_operand:DI 6 "register_operand"))]
"operands[3] != const0_rtx
&& (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
[(set (match_dup 6) (match_dup 7))
@@ -3704,12 +3089,12 @@
;; Prefer to use cmp and arithmetic when possible instead of a cmove.
(define_split
- [(set (match_operand 0 "register_operand" "")
+ [(set (match_operand 0 "register_operand")
(if_then_else (match_operator 1 "signed_comparison_operator"
- [(match_operand:DI 2 "reg_or_0_operand" "")
+ [(match_operand:DI 2 "reg_or_0_operand")
(const_int 0)])
- (match_operand 3 "const_int_operand" "")
- (match_operand 4 "const_int_operand" "")))]
+ (match_operand 3 "const_int_operand")
+ (match_operand 4 "const_int_operand")))]
""
[(const_int 0)]
{
@@ -3723,12 +3108,12 @@
;; ??? Why combine is allowed to create such non-canonical rtl, I don't know.
;; Oh well, we match it in movcc, so it must be partially our fault.
(define_split
- [(set (match_operand 0 "register_operand" "")
+ [(set (match_operand 0 "register_operand")
(if_then_else (match_operator 1 "signed_comparison_operator"
[(const_int 0)
- (match_operand:DI 2 "reg_or_0_operand" "")])
- (match_operand 3 "const_int_operand" "")
- (match_operand 4 "const_int_operand" "")))]
+ (match_operand:DI 2 "reg_or_0_operand")])
+ (match_operand 3 "const_int_operand")
+ (match_operand 4 "const_int_operand")))]
""
[(const_int 0)]
{
@@ -3904,10 +3289,10 @@
;; work differently, so we have different patterns for each.
(define_expand "call"
- [(use (match_operand:DI 0 "" ""))
- (use (match_operand 1 "" ""))
- (use (match_operand 2 "" ""))
- (use (match_operand 3 "" ""))]
+ [(use (match_operand:DI 0))
+ (use (match_operand 1))
+ (use (match_operand 2))
+ (use (match_operand 3))]
""
{
if (TARGET_ABI_OPEN_VMS)
@@ -3918,8 +3303,8 @@
})
(define_expand "sibcall"
- [(parallel [(call (mem:DI (match_operand 0 "" ""))
- (match_operand 1 "" ""))
+ [(parallel [(call (mem:DI (match_operand 0))
+ (match_operand 1))
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
"TARGET_ABI_OSF"
{
@@ -3928,8 +3313,8 @@
})
(define_expand "call_osf"
- [(parallel [(call (mem:DI (match_operand 0 "" ""))
- (match_operand 1 "" ""))
+ [(parallel [(call (mem:DI (match_operand 0))
+ (match_operand 1))
(use (reg:DI 29))
(clobber (reg:DI 26))])]
""
@@ -3947,8 +3332,8 @@
;; op 1: next_arg_reg (argument information value for R25)
;;
(define_expand "call_vms"
- [(parallel [(call (mem:DI (match_operand 0 "" ""))
- (match_operand 1 "" ""))
+ [(parallel [(call (mem:DI (match_operand 0))
+ (match_operand 1))
(use (match_dup 2))
(use (reg:DI 25))
(use (reg:DI 26))
@@ -3975,15 +3360,14 @@
operands[0], 8)));
operands[2] = operands[0];
}
-
})
(define_expand "call_value"
- [(use (match_operand 0 "" ""))
- (use (match_operand:DI 1 "" ""))
- (use (match_operand 2 "" ""))
- (use (match_operand 3 "" ""))
- (use (match_operand 4 "" ""))]
+ [(use (match_operand 0))
+ (use (match_operand:DI 1))
+ (use (match_operand 2))
+ (use (match_operand 3))
+ (use (match_operand 4))]
""
{
if (TARGET_ABI_OPEN_VMS)
@@ -3996,9 +3380,9 @@
})
(define_expand "sibcall_value"
- [(parallel [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand 1 "" ""))
- (match_operand 2 "" "")))
+ [(parallel [(set (match_operand 0)
+ (call (mem:DI (match_operand 1))
+ (match_operand 2)))
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
"TARGET_ABI_OSF"
{
@@ -4007,9 +3391,9 @@
})
(define_expand "call_value_osf"
- [(parallel [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand 1 "" ""))
- (match_operand 2 "" "")))
+ [(parallel [(set (match_operand 0)
+ (call (mem:DI (match_operand 1))
+ (match_operand 2)))
(use (reg:DI 29))
(clobber (reg:DI 26))])]
""
@@ -4022,9 +3406,9 @@
})
(define_expand "call_value_vms"
- [(parallel [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand:DI 1 "" ""))
- (match_operand 2 "" "")))
+ [(parallel [(set (match_operand 0)
+ (call (mem:DI (match_operand:DI 1))
+ (match_operand 2)))
(use (match_dup 3))
(use (reg:DI 25))
(use (reg:DI 26))
@@ -4055,7 +3439,7 @@
(define_insn "*call_osf_1_er_noreturn"
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(use (reg:DI 29))
(clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
@@ -4069,7 +3453,7 @@
(define_insn "*call_osf_1_er"
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(use (reg:DI 29))
(clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
@@ -4083,8 +3467,8 @@
;; We must use peep2 instead of a split because we need accurate life
;; information for $gp. Consider the case of { bar(); while (1); }.
(define_peephole2
- [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" ""))
- (match_operand 1 "" ""))
+ [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand"))
+ (match_operand 1))
(use (reg:DI 29))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
@@ -4114,8 +3498,8 @@
})
(define_peephole2
- [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" ""))
- (match_operand 1 "" ""))
+ [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand"))
+ (match_operand 1))
(use (reg:DI 29))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
@@ -4151,10 +3535,10 @@
(define_insn "*call_osf_2_er_nogp"
[(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(use (reg:DI 29))
- (use (match_operand 2 "" ""))
- (use (match_operand 3 "const_int_operand" ""))
+ (use (match_operand 2))
+ (use (match_operand 3 "const_int_operand"))
(clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%0),%2%J3"
@@ -4162,12 +3546,12 @@
(define_insn "*call_osf_2_er"
[(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(set (reg:DI 29)
- (unspec:DI [(reg:DI 29) (match_operand 4 "const_int_operand" "")]
+ (unspec:DI [(reg:DI 29) (match_operand 4 "const_int_operand")]
UNSPEC_LDGP1))
- (use (match_operand 2 "" ""))
- (use (match_operand 3 "const_int_operand" ""))
+ (use (match_operand 2))
+ (use (match_operand 3 "const_int_operand"))
(clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%0),%2%J3\;ldah $29,0($26)\t\t!gpdisp!%4"
@@ -4177,7 +3561,7 @@
(define_insn "*call_osf_1_noreturn"
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(use (reg:DI 29))
(clobber (reg:DI 26))]
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
@@ -4191,7 +3575,7 @@
(define_insn "*call_osf_1"
[(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(use (reg:DI 29))
(clobber (reg:DI 26))]
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
@@ -4204,7 +3588,7 @@
(define_insn "*sibcall_osf_1_er"
[(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
@@ -4217,7 +3601,7 @@
;; doesn't do what we want.
(define_insn "*sibcall_osf_1"
[(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
@@ -4231,7 +3615,7 @@
; Please do not molest.
(define_insn "*call_vms_1"
[(call (mem:DI (match_operand:DI 0 "call_operand" "r,s"))
- (match_operand 1 "" ""))
+ (match_operand 1))
(use (match_operand:DI 2 "nonmemory_operand" "r,n"))
(use (reg:DI 25))
(use (reg:DI 26))
@@ -4256,10 +3640,10 @@
;; Call subroutine returning any type.
(define_expand "untyped_call"
- [(parallel [(call (match_operand 0 "" "")
+ [(parallel [(call (match_operand 0)
(const_int 0))
- (match_operand 1 "" "")
- (match_operand 2 "" "")])]
+ (match_operand 1)
+ (match_operand 2)])]
""
{
int i;
@@ -4293,15 +3677,14 @@
(define_insn "jump"
[(set (pc)
- (label_ref (match_operand 0 "" "")))]
+ (label_ref (match_operand 0)))]
""
"br $31,%l0"
[(set_attr "type" "ibr")])
(define_expand "return"
[(return)]
- "direct_return ()"
- "")
+ "direct_return ()")
(define_insn "*return_internal"
[(return)]
@@ -4317,8 +3700,8 @@
(define_expand "tablejump"
[(parallel [(set (pc)
- (match_operand 0 "register_operand" ""))
- (use (label_ref:DI (match_operand 1 "" "")))])]
+ (match_operand 0 "register_operand"))
+ (use (label_ref:DI (match_operand 1)))])]
""
{
if (TARGET_ABI_OSF)
@@ -4333,7 +3716,7 @@
(define_insn "*tablejump_internal"
[(set (pc)
(match_operand:DI 0 "register_operand" "r"))
- (use (label_ref (match_operand 1 "" "")))]
+ (use (label_ref (match_operand 1)))]
""
"jmp $31,(%0),0"
[(set_attr "type" "ibr")])
@@ -4347,8 +3730,8 @@
[(set_attr "type" "callpal")])
(define_expand "clear_cache"
- [(match_operand:DI 0 "") ; region start
- (match_operand:DI 1 "")] ; region end
+ [(match_operand:DI 0) ; region start
+ (match_operand:DI 1)] ; region end
""
{
emit_insn (gen_imb ());
@@ -4365,7 +3748,7 @@
;; For userland, we load the thread pointer from the TCB.
;; For the kernel, we load the per-cpu private value.
-(define_insn "load_tp"
+(define_insn "get_thread_pointerdi"
[(set (match_operand:DI 0 "register_operand" "=v")
(unspec:DI [(const_int 0)] UNSPEC_TP))]
"TARGET_ABI_OSF"
@@ -4382,11 +3765,10 @@
;; quantity for CSE, we have to use a volatile unspec, and then there's
;; not much point in creating an R16_REG register class.
-(define_expand "set_tp"
- [(set (reg:DI 16) (match_operand:DI 0 "input_operand" ""))
+(define_expand "set_thread_pointerdi"
+ [(set (reg:DI 16) (match_operand:DI 0 "input_operand"))
(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
- "TARGET_ABI_OSF"
- "")
+ "TARGET_ABI_OSF")
(define_insn "*set_tp"
[(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
@@ -4402,8 +3784,8 @@
;; Special builtins for establishing and reverting VMS condition handlers.
(define_expand "builtin_establish_vms_condition_handler"
- [(set (reg:DI 0) (match_operand:DI 0 "register_operand" ""))
- (use (match_operand:DI 1 "address_operand" ""))]
+ [(set (reg:DI 0) (match_operand:DI 0 "register_operand"))
+ (use (match_operand:DI 1 "address_operand"))]
"TARGET_ABI_OPEN_VMS"
{
alpha_expand_builtin_establish_vms_condition_handler (operands[0],
@@ -4411,19 +3793,17 @@
})
(define_expand "builtin_revert_vms_condition_handler"
- [(set (reg:DI 0) (match_operand:DI 0 "register_operand" ""))]
+ [(set (reg:DI 0) (match_operand:DI 0 "register_operand"))]
"TARGET_ABI_OPEN_VMS"
-{
- alpha_expand_builtin_revert_vms_condition_handler (operands[0]);
-})
+ "alpha_expand_builtin_revert_vms_condition_handler (operands[0]);")
;; Finally, we have the basic data motion insns. The byte and word insns
;; are done via define_expand. Start with the floating-point insns, since
;; they are simpler.
(define_expand "movsf"
- [(set (match_operand:SF 0 "nonimmediate_operand" "")
- (match_operand:SF 1 "general_operand" ""))]
+ [(set (match_operand:SF 0 "nonimmediate_operand")
+ (match_operand:SF 1 "general_operand"))]
""
{
if (MEM_P (operands[0])
@@ -4449,8 +3829,8 @@
(set_attr "isa" "*,*,*,*,*,*,fix,fix")])
(define_expand "movdf"
- [(set (match_operand:DF 0 "nonimmediate_operand" "")
- (match_operand:DF 1 "general_operand" ""))]
+ [(set (match_operand:DF 0 "nonimmediate_operand")
+ (match_operand:DF 1 "general_operand"))]
""
{
if (MEM_P (operands[0])
@@ -4480,8 +3860,8 @@
;; ??? Is this still true now that we have the lower-subreg pass?
(define_expand "movtf"
- [(set (match_operand:TF 0 "nonimmediate_operand" "")
- (match_operand:TF 1 "general_operand" ""))]
+ [(set (match_operand:TF 0 "nonimmediate_operand")
+ (match_operand:TF 1 "general_operand"))]
""
{
if (MEM_P (operands[0])
@@ -4498,16 +3878,14 @@
"reload_completed"
[(set (match_dup 0) (match_dup 2))
(set (match_dup 1) (match_dup 3))]
-{
- alpha_split_tmode_pair (operands, TFmode, true);
-})
+ "alpha_split_tmode_pair (operands, TFmode, true);")
;; We do two major things here: handle mem->mem and construct long
;; constants.
(define_expand "movsi"
- [(set (match_operand:SI 0 "nonimmediate_operand" "")
- (match_operand:SI 1 "general_operand" ""))]
+ [(set (match_operand:SI 0 "nonimmediate_operand")
+ (match_operand:SI 1 "general_operand"))]
""
{
if (alpha_expand_mov (SImode, operands))
@@ -4534,8 +3912,8 @@
;; sequence.
(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "non_add_const_operand" ""))]
+ [(set (match_operand:SI 0 "register_operand")
+ (match_operand:SI 1 "non_add_const_operand"))]
""
[(const_int 0)]
{
@@ -4548,7 +3926,7 @@
(define_insn "*movdi_er_low_l"
[(set (match_operand:DI 0 "register_operand" "=r")
(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "local_symbolic_operand" "")))]
+ (match_operand:DI 2 "local_symbolic_operand")))]
"TARGET_EXPLICIT_RELOCS"
{
if (true_regnum (operands[1]) == 29)
@@ -4559,16 +3937,16 @@
[(set_attr "usegp" "yes")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "small_symbolic_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "small_symbolic_operand"))]
"TARGET_EXPLICIT_RELOCS && reload_completed"
[(set (match_dup 0)
(lo_sum:DI (match_dup 2) (match_dup 1)))]
"operands[2] = pic_offset_table_rtx;")
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "local_symbolic_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "local_symbolic_operand"))]
"TARGET_EXPLICIT_RELOCS && reload_completed"
[(set (match_dup 0)
(plus:DI (match_dup 2) (high:DI (match_dup 1))))
@@ -4577,7 +3955,7 @@
"operands[2] = pic_offset_table_rtx;")
(define_split
- [(match_operand 0 "some_small_symbolic_operand" "")]
+ [(match_operand 0 "some_small_symbolic_operand")]
""
[(match_dup 0)]
"operands[0] = split_small_symbolic_operand (operands[0]);")
@@ -4587,8 +3965,8 @@
(define_insn "movdi_er_high_g"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "symbolic_operand" "")
- (match_operand 3 "const_int_operand" "")]
+ (match_operand:DI 2 "symbolic_operand")
+ (match_operand 3 "const_int_operand")]
UNSPEC_LITERAL))]
"TARGET_EXPLICIT_RELOCS"
{
@@ -4600,8 +3978,8 @@
[(set_attr "type" "ldsym")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "global_symbolic_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "global_symbolic_operand"))]
"TARGET_EXPLICIT_RELOCS && reload_completed"
[(set (match_dup 0)
(unspec:DI [(match_dup 2)
@@ -4612,8 +3990,8 @@
(define_insn "movdi_er_tlsgd"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "symbolic_operand" "")
- (match_operand 3 "const_int_operand" "")]
+ (match_operand:DI 2 "symbolic_operand")
+ (match_operand 3 "const_int_operand")]
UNSPEC_TLSGD))]
"HAVE_AS_TLS"
{
@@ -4626,7 +4004,7 @@
(define_insn "movdi_er_tlsldm"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "")]
+ (match_operand 2 "const_int_operand")]
UNSPEC_TLSLDM))]
"HAVE_AS_TLS"
{
@@ -4639,7 +4017,7 @@
(define_insn "*movdi_er_gotdtp"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "symbolic_operand" "")]
+ (match_operand:DI 2 "symbolic_operand")]
UNSPEC_DTPREL))]
"HAVE_AS_TLS"
"ldq %0,%2(%1)\t\t!gotdtprel"
@@ -4647,8 +4025,8 @@
(set_attr "usegp" "yes")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "gotdtp_symbolic_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "gotdtp_symbolic_operand"))]
"HAVE_AS_TLS && reload_completed"
[(set (match_dup 0)
(unspec:DI [(match_dup 2)
@@ -4661,7 +4039,7 @@
(define_insn "*movdi_er_gottp"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "symbolic_operand" "")]
+ (match_operand:DI 2 "symbolic_operand")]
UNSPEC_TPREL))]
"HAVE_AS_TLS"
"ldq %0,%2(%1)\t\t!gottprel"
@@ -4669,8 +4047,8 @@
(set_attr "usegp" "yes")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "gottp_symbolic_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "gottp_symbolic_operand"))]
"HAVE_AS_TLS && reload_completed"
[(set (match_dup 0)
(unspec:DI [(match_dup 2)
@@ -4722,8 +4100,8 @@
;; memory, and construct long 32-bit constants.
(define_expand "movdi"
- [(set (match_operand:DI 0 "nonimmediate_operand" "")
- (match_operand:DI 1 "general_operand" ""))]
+ [(set (match_operand:DI 0 "nonimmediate_operand")
+ (match_operand:DI 1 "general_operand"))]
""
{
if (alpha_expand_mov (DImode, operands))
@@ -4734,8 +4112,8 @@
;; sequence.
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "non_add_const_operand" ""))]
+ [(set (match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "non_add_const_operand"))]
""
[(const_int 0)]
{
@@ -4761,13 +4139,11 @@
"reload_completed"
[(set (match_dup 0) (match_dup 2))
(set (match_dup 1) (match_dup 3))]
-{
- alpha_split_tmode_pair (operands, TImode, true);
-})
+ "alpha_split_tmode_pair (operands, TImode, true);")
(define_expand "movti"
- [(set (match_operand:TI 0 "nonimmediate_operand" "")
- (match_operand:TI 1 "general_operand" ""))]
+ [(set (match_operand:TI 0 "nonimmediate_operand")
+ (match_operand:TI 1 "general_operand"))]
""
{
if (MEM_P (operands[0])
@@ -4829,26 +4205,20 @@
;; same register. It is allowed to conflict with operand 1 as well.
(define_expand "aligned_loadqi"
- [(set (match_operand:SI 3 "register_operand" "")
- (match_operand:SI 1 "memory_operand" ""))
- (set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:SI 3 "register_operand")
+ (match_operand:SI 1 "memory_operand"))
+ (set (match_operand:DI 0 "register_operand")
(zero_extract:DI (subreg:DI (match_dup 3) 0)
(const_int 8)
- (match_operand:DI 2 "const_int_operand" "")))]
-
- ""
- "")
+ (match_operand:DI 2 "const_int_operand")))])
(define_expand "aligned_loadhi"
- [(set (match_operand:SI 3 "register_operand" "")
- (match_operand:SI 1 "memory_operand" ""))
- (set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:SI 3 "register_operand")
+ (match_operand:SI 1 "memory_operand"))
+ (set (match_operand:DI 0 "register_operand")
(zero_extract:DI (subreg:DI (match_dup 3) 0)
(const_int 16)
- (match_operand:DI 2 "const_int_operand" "")))]
-
- ""
- "")
+ (match_operand:DI 2 "const_int_operand")))])
;; Similar for unaligned loads, where we use the sequence from the
;; Alpha Architecture manual. We have to distinguish between little-endian
@@ -4858,30 +4228,26 @@
;; operand 3 can overlap the input and output registers.
(define_expand "unaligned_loadqi"
- [(set (match_operand:DI 2 "register_operand" "")
- (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
+ [(set (match_operand:DI 2 "register_operand")
+ (mem:DI (and:DI (match_operand:DI 1 "address_operand")
(const_int -8))))
- (set (match_operand:DI 3 "register_operand" "")
+ (set (match_operand:DI 3 "register_operand")
(match_dup 1))
- (set (match_operand:DI 0 "register_operand" "")
+ (set (match_operand:DI 0 "register_operand")
(zero_extract:DI (match_dup 2)
(const_int 8)
- (ashift:DI (match_dup 3) (const_int 3))))]
- ""
- "")
+ (ashift:DI (match_dup 3) (const_int 3))))])
(define_expand "unaligned_loadhi"
- [(set (match_operand:DI 2 "register_operand" "")
- (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
+ [(set (match_operand:DI 2 "register_operand")
+ (mem:DI (and:DI (match_operand:DI 1 "address_operand")
(const_int -8))))
- (set (match_operand:DI 3 "register_operand" "")
+ (set (match_operand:DI 3 "register_operand")
(match_dup 1))
- (set (match_operand:DI 0 "register_operand" "")
+ (set (match_operand:DI 0 "register_operand")
(zero_extract:DI (match_dup 2)
(const_int 16)
- (ashift:DI (match_dup 3) (const_int 3))))]
- ""
- "")
+ (ashift:DI (match_dup 3) (const_int 3))))])
;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
;; aligned SImode MEM. Operand 1 is the register containing the
@@ -4889,13 +4255,13 @@
;; the value should be placed. Operands 3 and 4 are SImode temporaries.
(define_expand "aligned_store"
- [(set (match_operand:SI 3 "register_operand" "")
- (match_operand:SI 0 "memory_operand" ""))
+ [(set (match_operand:SI 3 "register_operand")
+ (match_operand:SI 0 "memory_operand"))
(set (subreg:DI (match_dup 3) 0)
(and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
- (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
- (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
- (match_operand:DI 2 "const_int_operand" "")))
+ (set (subreg:DI (match_operand:SI 4 "register_operand") 0)
+ (ashift:DI (zero_extend:DI (match_operand 1 "register_operand"))
+ (match_operand:DI 2 "const_int_operand")))
(set (subreg:DI (match_dup 4) 0)
(ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
(set (match_dup 0) (match_dup 4))]
@@ -4912,56 +4278,38 @@
;; be the same temporary, if desired. If the address is in a register,
;; operand 2 can be that register.
-(define_expand "unaligned_storeqi"
- [(set (match_operand:DI 3 "register_operand" "")
- (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
+(define_expand "unaligned_store<mode>"
+ [(set (match_operand:DI 3 "register_operand")
+ (mem:DI (and:DI (match_operand:DI 0 "address_operand")
(const_int -8))))
- (set (match_operand:DI 2 "register_operand" "")
+ (set (match_operand:DI 2 "register_operand")
(match_dup 0))
(set (match_dup 3)
- (and:DI (not:DI (ashift:DI (const_int 255)
+ (and:DI (not:DI (ashift:DI (match_dup 5)
(ashift:DI (match_dup 2) (const_int 3))))
(match_dup 3)))
- (set (match_operand:DI 4 "register_operand" "")
- (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
+ (set (match_operand:DI 4 "register_operand")
+ (ashift:DI (zero_extend:DI
+ (match_operand:I12MODE 1 "register_operand"))
(ashift:DI (match_dup 2) (const_int 3))))
(set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
(set (mem:DI (and:DI (match_dup 0) (const_int -8)))
(match_dup 4))]
""
- "")
-
-(define_expand "unaligned_storehi"
- [(set (match_operand:DI 3 "register_operand" "")
- (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
- (const_int -8))))
- (set (match_operand:DI 2 "register_operand" "")
- (match_dup 0))
- (set (match_dup 3)
- (and:DI (not:DI (ashift:DI (const_int 65535)
- (ashift:DI (match_dup 2) (const_int 3))))
- (match_dup 3)))
- (set (match_operand:DI 4 "register_operand" "")
- (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
- (ashift:DI (match_dup 2) (const_int 3))))
- (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
- (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
- (match_dup 4))]
- ""
- "")
+ "operands[5] = GEN_INT (GET_MODE_MASK (<MODE>mode));")
;; Here are the define_expand's for QI and HI moves that use the above
;; patterns. We have the normal sets, plus the ones that need scratch
;; registers for reload.
-(define_expand "movqi"
- [(set (match_operand:QI 0 "nonimmediate_operand" "")
- (match_operand:QI 1 "general_operand" ""))]
+(define_expand "mov<mode>"
+ [(set (match_operand:I12MODE 0 "nonimmediate_operand")
+ (match_operand:I12MODE 1 "general_operand"))]
""
{
if (TARGET_BWX
- ? alpha_expand_mov (QImode, operands)
- : alpha_expand_mov_nobwx (QImode, operands))
+ ? alpha_expand_mov (<MODE>mode, operands)
+ : alpha_expand_mov_nobwx (<MODE>mode, operands))
DONE;
})
@@ -4978,17 +4326,6 @@
[(set_attr "type" "ilog,iadd,ild,ist")
(set_attr "isa" "*,*,bwx,bwx")])
-(define_expand "movhi"
- [(set (match_operand:HI 0 "nonimmediate_operand" "")
- (match_operand:HI 1 "general_operand" ""))]
- ""
-{
- if (TARGET_BWX
- ? alpha_expand_mov (HImode, operands)
- : alpha_expand_mov_nobwx (HImode, operands))
- DONE;
-})
-
(define_insn "*movhi"
[(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
(match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
@@ -5005,8 +4342,8 @@
;; We need to hook into the extra support that we have for HImode
;; reloads when BWX insns are not available.
(define_expand "movcqi"
- [(set (match_operand:CQI 0 "nonimmediate_operand" "")
- (match_operand:CQI 1 "general_operand" ""))]
+ [(set (match_operand:CQI 0 "nonimmediate_operand")
+ (match_operand:CQI 1 "general_operand"))]
"!TARGET_BWX"
{
if (GET_CODE (operands[0]) == CONCAT || GET_CODE (operands[1]) == CONCAT)
@@ -5162,10 +4499,11 @@
;; Vector operations
(define_mode_iterator VEC [V8QI V4HI V2SI])
+(define_mode_iterator VEC12 [V8QI V4HI])
(define_expand "mov<mode>"
- [(set (match_operand:VEC 0 "nonimmediate_operand" "")
- (match_operand:VEC 1 "general_operand" ""))]
+ [(set (match_operand:VEC 0 "nonimmediate_operand")
+ (match_operand:VEC 1 "general_operand"))]
""
{
if (alpha_expand_mov (<MODE>mode, operands))
@@ -5173,8 +4511,8 @@
})
(define_split
- [(set (match_operand:VEC 0 "register_operand" "")
- (match_operand:VEC 1 "non_zero_const_operand" ""))]
+ [(set (match_operand:VEC 0 "register_operand")
+ (match_operand:VEC 1 "non_zero_const_operand"))]
""
[(const_int 0)]
{
@@ -5186,8 +4524,8 @@
(define_expand "movmisalign<mode>"
- [(set (match_operand:VEC 0 "nonimmediate_operand" "")
- (match_operand:VEC 1 "general_operand" ""))]
+ [(set (match_operand:VEC 0 "nonimmediate_operand")
+ (match_operand:VEC 1 "general_operand"))]
""
{
alpha_expand_movmisalign (<MODE>mode, operands);
@@ -5212,68 +4550,13 @@
[(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst,ftoi,itof")
(set_attr "isa" "*,*,*,*,*,*,*,fix,fix")])
-(define_insn "uminv8qi3"
- [(set (match_operand:V8QI 0 "register_operand" "=r")
- (umin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
- (match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
- "TARGET_MAX"
- "minub8 %r1,%r2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "sminv8qi3"
- [(set (match_operand:V8QI 0 "register_operand" "=r")
- (smin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
- (match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
- "TARGET_MAX"
- "minsb8 %r1,%r2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "uminv4hi3"
- [(set (match_operand:V4HI 0 "register_operand" "=r")
- (umin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
- (match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
- "TARGET_MAX"
- "minuw4 %r1,%r2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "sminv4hi3"
- [(set (match_operand:V4HI 0 "register_operand" "=r")
- (smin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
- (match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
- "TARGET_MAX"
- "minsw4 %r1,%r2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "umaxv8qi3"
- [(set (match_operand:V8QI 0 "register_operand" "=r")
- (umax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
- (match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
- "TARGET_MAX"
- "maxub8 %r1,%r2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "smaxv8qi3"
- [(set (match_operand:V8QI 0 "register_operand" "=r")
- (smax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
- (match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
+(define_insn "<code><mode>3"
+ [(set (match_operand:VEC12 0 "register_operand" "=r")
+ (any_maxmin:VEC12
+ (match_operand:VEC12 1 "reg_or_0_operand" "rW")
+ (match_operand:VEC12 2 "reg_or_0_operand" "rW")))]
"TARGET_MAX"
- "maxsb8 %r1,%r2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "umaxv4hi3"
- [(set (match_operand:V4HI 0 "register_operand" "=r")
- (umax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
- (match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
- "TARGET_MAX"
- "maxuw4 %r1,%r2,%0"
- [(set_attr "type" "mvi")])
-
-(define_insn "smaxv4hi3"
- [(set (match_operand:V4HI 0 "register_operand" "=r")
- (smax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
- (match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
- "TARGET_MAX"
- "maxsw4 %r1,%r2,%0"
+ "<maxmin><modesuffix> %r1,%r2,%0"
[(set_attr "type" "mvi")])
(define_insn "one_cmpl<mode>2"
@@ -5332,9 +4615,9 @@
[(set_attr "type" "ilog")])
(define_expand "vec_shl_<mode>"
- [(set (match_operand:VEC 0 "register_operand" "")
- (ashift:DI (match_operand:VEC 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_6bit_operand" "")))]
+ [(set (match_operand:VEC 0 "register_operand")
+ (ashift:DI (match_operand:VEC 1 "register_operand")
+ (match_operand:DI 2 "reg_or_6bit_operand")))]
""
{
operands[0] = gen_lowpart (DImode, operands[0]);
@@ -5342,9 +4625,9 @@
})
(define_expand "vec_shr_<mode>"
- [(set (match_operand:VEC 0 "register_operand" "")
- (lshiftrt:DI (match_operand:VEC 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_6bit_operand" "")))]
+ [(set (match_operand:VEC 0 "register_operand")
+ (lshiftrt:DI (match_operand:VEC 1 "register_operand")
+ (match_operand:DI 2 "reg_or_6bit_operand")))]
""
{
operands[0] = gen_lowpart (DImode, operands[0]);
@@ -5354,10 +4637,10 @@
;; Bit field extract patterns which use ext[wlq][lh]
(define_expand "extv"
- [(set (match_operand:DI 0 "register_operand" "")
- (sign_extract:DI (match_operand:QI 1 "memory_operand" "")
- (match_operand:DI 2 "immediate_operand" "")
- (match_operand:DI 3 "immediate_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (sign_extract:DI (match_operand:QI 1 "memory_operand")
+ (match_operand:DI 2 "immediate_operand")
+ (match_operand:DI 3 "immediate_operand")))]
""
{
int ofs;
@@ -5384,10 +4667,10 @@
})
(define_expand "extzv"
- [(set (match_operand:DI 0 "register_operand" "")
- (zero_extract:DI (match_operand:DI 1 "nonimmediate_operand" "")
- (match_operand:DI 2 "immediate_operand" "")
- (match_operand:DI 3 "immediate_operand" "")))]
+ [(set (match_operand:DI 0 "register_operand")
+ (zero_extract:DI (match_operand:DI 1 "nonimmediate_operand")
+ (match_operand:DI 2 "immediate_operand")
+ (match_operand:DI 3 "immediate_operand")))]
""
{
/* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries. */
@@ -5417,10 +4700,10 @@
})
(define_expand "insv"
- [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "")
- (match_operand:DI 1 "immediate_operand" "")
- (match_operand:DI 2 "immediate_operand" ""))
- (match_operand:DI 3 "register_operand" ""))]
+ [(set (zero_extract:DI (match_operand:QI 0 "memory_operand")
+ (match_operand:DI 1 "immediate_operand")
+ (match_operand:DI 2 "immediate_operand"))
+ (match_operand:DI 3 "register_operand"))]
""
{
int ofs;
@@ -5452,10 +4735,10 @@
;; Argument 3 is the alignment
(define_expand "movmemqi"
- [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
- (match_operand:BLK 1 "memory_operand" ""))
- (use (match_operand:DI 2 "immediate_operand" ""))
- (use (match_operand:DI 3 "immediate_operand" ""))])]
+ [(parallel [(set (match_operand:BLK 0 "memory_operand")
+ (match_operand:BLK 1 "memory_operand"))
+ (use (match_operand:DI 2 "immediate_operand"))
+ (use (match_operand:DI 3 "immediate_operand"))])]
""
{
if (alpha_expand_block_move (operands))
@@ -5465,10 +4748,10 @@
})
(define_expand "movmemdi"
- [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
- (match_operand:BLK 1 "memory_operand" ""))
- (use (match_operand:DI 2 "immediate_operand" ""))
- (use (match_operand:DI 3 "immediate_operand" ""))
+ [(parallel [(set (match_operand:BLK 0 "memory_operand")
+ (match_operand:BLK 1 "memory_operand"))
+ (use (match_operand:DI 2 "immediate_operand"))
+ (use (match_operand:DI 3 "immediate_operand"))
(use (match_dup 4))
(clobber (reg:DI 25))
(clobber (reg:DI 16))
@@ -5479,15 +4762,13 @@
(clobber (reg:DI 26))
(clobber (reg:DI 27))])]
"TARGET_ABI_OPEN_VMS"
-{
- operands[4] = gen_rtx_SYMBOL_REF (Pmode, "OTS$MOVE");
-})
+ "operands[4] = gen_rtx_SYMBOL_REF (Pmode, \"OTS$MOVE\");")
(define_insn "*movmemdi_1"
[(set (match_operand:BLK 0 "memory_operand" "=m,=m")
(match_operand:BLK 1 "memory_operand" "m,m"))
(use (match_operand:DI 2 "nonmemory_operand" "r,i"))
- (use (match_operand:DI 3 "immediate_operand" ""))
+ (use (match_operand:DI 3 "immediate_operand"))
(use (match_operand:DI 4 "call_operand" "i,i"))
(clobber (reg:DI 25))
(clobber (reg:DI 16))
@@ -5514,10 +4795,10 @@
(set_attr "length" "28")])
(define_expand "setmemqi"
- [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
- (match_operand 2 "const_int_operand" ""))
- (use (match_operand:DI 1 "immediate_operand" ""))
- (use (match_operand:DI 3 "immediate_operand" ""))])]
+ [(parallel [(set (match_operand:BLK 0 "memory_operand")
+ (match_operand 2 "const_int_operand"))
+ (use (match_operand:DI 1 "immediate_operand"))
+ (use (match_operand:DI 3 "immediate_operand"))])]
""
{
/* If value to set is not zero, use the library routine. */
@@ -5531,10 +4812,10 @@
})
(define_expand "setmemdi"
- [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
- (match_operand 2 "const_int_operand" ""))
- (use (match_operand:DI 1 "immediate_operand" ""))
- (use (match_operand:DI 3 "immediate_operand" ""))
+ [(parallel [(set (match_operand:BLK 0 "memory_operand")
+ (match_operand 2 "const_int_operand"))
+ (use (match_operand:DI 1 "immediate_operand"))
+ (use (match_operand:DI 3 "immediate_operand"))
(use (match_dup 4))
(clobber (reg:DI 25))
(clobber (reg:DI 16))
@@ -5554,7 +4835,7 @@
[(set (match_operand:BLK 0 "memory_operand" "=m,=m")
(const_int 0))
(use (match_operand:DI 1 "nonmemory_operand" "r,i"))
- (use (match_operand:DI 2 "immediate_operand" ""))
+ (use (match_operand:DI 2 "immediate_operand"))
(use (match_operand:DI 3 "call_operand" "i,i"))
(clobber (reg:DI 25))
(clobber (reg:DI 16))
@@ -5580,7 +4861,7 @@
;; Subroutine of stack space allocation. Perform a stack probe.
(define_expand "probe_stack"
- [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
+ [(set (match_dup 1) (match_operand:DI 0 "const_int_operand"))]
""
{
operands[1] = gen_rtx_MEM (DImode, plus_constant (Pmode, stack_pointer_rtx,
@@ -5599,7 +4880,7 @@
(define_expand "allocate_stack"
[(set (reg:DI 30)
(plus:DI (reg:DI 30)
- (match_operand:DI 1 "reg_or_cint_operand" "")))
+ (match_operand:DI 1 "reg_or_cint_operand")))
(set (match_operand:DI 0 "register_operand" "=r")
(match_dup 2))]
""
@@ -5687,7 +4968,7 @@
(set_attr "type" "multi")])
(define_expand "prologue"
- [(clobber (const_int 0))]
+ [(const_int 0)]
""
{
alpha_expand_prologue ();
@@ -5718,7 +4999,7 @@
(define_insn "*ldgp_er_1"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "")]
+ (match_operand 2 "const_int_operand")]
UNSPECV_LDGP1))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"ldah %0,0(%1)\t\t!gpdisp!%2"
@@ -5727,7 +5008,7 @@
(define_insn "*ldgp_er_2"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "")]
+ (match_operand 2 "const_int_operand")]
UNSPEC_LDGP2))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"lda %0,0(%1)\t\t!gpdisp!%2"
@@ -5736,7 +5017,7 @@
(define_insn "*prologue_ldgp_er_2"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "")]
+ (match_operand 2 "const_int_operand")]
UNSPECV_PLDGP2))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:"
@@ -5745,7 +5026,7 @@
(define_insn "*prologue_ldgp_1"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "")]
+ (match_operand 2 "const_int_operand")]
UNSPECV_LDGP1))]
""
"ldgp %0,0(%1)\n$%~..ng:"
@@ -5754,10 +5035,10 @@
(define_insn "*prologue_ldgp_2"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "")]
+ (match_operand 2 "const_int_operand")]
UNSPECV_PLDGP2))]
""
- "")
+ )
;; The _mcount profiling hook has special calling conventions, and
;; does not clobber all the registers that a normal call would. So
@@ -5787,9 +5068,7 @@
(define_expand "epilogue"
[(return)]
""
-{
- alpha_expand_epilogue ();
-})
+ "alpha_expand_epilogue ();")
(define_expand "sibcall_epilogue"
[(return)]
@@ -5835,12 +5114,11 @@
[(set_attr "type" "ibr")])
(define_expand "builtin_setjmp_receiver"
- [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
- "TARGET_ABI_OSF"
- "")
+ [(unspec_volatile [(label_ref (match_operand 0))] UNSPECV_SETJMPR)]
+ "TARGET_ABI_OSF")
(define_insn_and_split "*builtin_setjmp_receiver_1"
- [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR)]
+ [(unspec_volatile [(match_operand 0)] UNSPECV_SETJMPR)]
"TARGET_ABI_OSF"
{
if (TARGET_EXPLICIT_RELOCS)
@@ -5865,7 +5143,7 @@
(set_attr "type" "multi")])
(define_insn "*builtin_setjmp_receiver_er_sl_1"
- [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)]
+ [(unspec_volatile [(match_operand 0)] UNSPECV_SETJMPR_ER)]
"TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS"
"lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
@@ -5919,8 +5197,7 @@
(set (reg:DI 27) (mem:DI (reg:DI 29)))
(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
(use (reg:DI 27))]
- "TARGET_ABI_OPEN_VMS"
- "")
+ "TARGET_ABI_OPEN_VMS")
(define_insn "arg_home"
[(unspec [(const_int 0)] UNSPEC_ARG_HOME)
@@ -6035,9 +5312,9 @@
[(set_attr "type" "icmp")])
(define_expand "extbl"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (8), operands[2]));
@@ -6045,9 +5322,9 @@
})
(define_expand "extwl"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (16), operands[2]));
@@ -6055,9 +5332,9 @@
})
(define_expand "extll"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (32), operands[2]));
@@ -6065,9 +5342,9 @@
})
(define_expand "extql"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (64), operands[2]));
@@ -6075,9 +5352,9 @@
})
(define_expand "builtin_insbl"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
operands[1] = gen_lowpart (QImode, operands[1]);
@@ -6086,9 +5363,9 @@
})
(define_expand "builtin_inswl"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
operands[1] = gen_lowpart (HImode, operands[1]);
@@ -6097,9 +5374,9 @@
})
(define_expand "builtin_insll"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
operands[1] = gen_lowpart (SImode, operands[1]);
@@ -6108,9 +5385,9 @@
})
(define_expand "inswh"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (16), operands[2]));
@@ -6118,9 +5395,9 @@
})
(define_expand "inslh"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (32), operands[2]));
@@ -6128,9 +5405,9 @@
})
(define_expand "insqh"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (64), operands[2]));
@@ -6138,9 +5415,9 @@
})
(define_expand "mskbl"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
rtx mask = GEN_INT (0xff);
@@ -6149,9 +5426,9 @@
})
(define_expand "mskwl"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
rtx mask = GEN_INT (0xffff);
@@ -6160,9 +5437,9 @@
})
(define_expand "mskll"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
rtx mask = immed_double_const (0xffffffff, 0, DImode);
@@ -6171,9 +5448,9 @@
})
(define_expand "mskql"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
rtx mask = constm1_rtx;
@@ -6182,9 +5459,9 @@
})
(define_expand "mskwh"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (16), operands[2]));
@@ -6192,9 +5469,9 @@
})
(define_expand "msklh"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (32), operands[2]));
@@ -6202,9 +5479,9 @@
})
(define_expand "mskqh"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "register_operand" "")
- (match_operand:DI 2 "reg_or_8bit_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "reg_or_8bit_operand")]
""
{
emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (64), operands[2]));
@@ -6212,11 +5489,11 @@
})
(define_expand "builtin_zap"
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(and:DI (unspec:DI
- [(match_operand:DI 2 "reg_or_cint_operand" "")]
+ [(match_operand:DI 2 "reg_or_cint_operand")]
UNSPEC_ZAP)
- (match_operand:DI 1 "reg_or_cint_operand" "")))]
+ (match_operand:DI 1 "reg_or_cint_operand")))]
""
{
if (CONST_INT_P (operands[2]))
@@ -6258,11 +5535,11 @@
[(set_attr "type" "shift,shift,ilog,shift")])
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(and:DI (unspec:DI
- [(match_operand:QI 2 "const_int_operand" "")]
+ [(match_operand:QI 2 "const_int_operand")]
UNSPEC_ZAP)
- (match_operand:DI 1 "const_int_operand" "")))]
+ (match_operand:DI 1 "const_int_operand")))]
""
[(const_int 0)]
{
@@ -6282,11 +5559,11 @@
})
(define_split
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(and:DI (unspec:DI
- [(match_operand:QI 2 "const_int_operand" "")]
+ [(match_operand:QI 2 "const_int_operand")]
UNSPEC_ZAP)
- (match_operand:DI 1 "register_operand" "")))]
+ (match_operand:DI 1 "register_operand")))]
""
[(set (match_dup 0)
(and:DI (match_dup 1) (match_dup 2)))]
@@ -6305,11 +5582,11 @@
})
(define_expand "builtin_zapnot"
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(and:DI (unspec:DI
- [(not:QI (match_operand:DI 2 "reg_or_cint_operand" ""))]
+ [(not:QI (match_operand:DI 2 "reg_or_cint_operand"))]
UNSPEC_ZAP)
- (match_operand:DI 1 "reg_or_cint_operand" "")))]
+ (match_operand:DI 1 "reg_or_cint_operand")))]
""
{
if (CONST_INT_P (operands[2]))
@@ -6369,9 +5646,9 @@
[(set_attr "type" "ilog")])
(define_expand "builtin_minub8"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_0_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_0_operand")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_uminv8qi3, V8QImode, operands[0],
@@ -6380,9 +5657,9 @@
})
(define_expand "builtin_minsb8"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_0_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_0_operand")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_sminv8qi3, V8QImode, operands[0],
@@ -6391,9 +5668,9 @@
})
(define_expand "builtin_minuw4"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_0_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_0_operand")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_uminv4hi3, V4HImode, operands[0],
@@ -6402,9 +5679,9 @@
})
(define_expand "builtin_minsw4"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_0_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_0_operand")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_sminv4hi3, V4HImode, operands[0],
@@ -6413,9 +5690,9 @@
})
(define_expand "builtin_maxub8"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_0_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_0_operand")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_umaxv8qi3, V8QImode, operands[0],
@@ -6424,9 +5701,9 @@
})
(define_expand "builtin_maxsb8"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_0_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_0_operand")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_smaxv8qi3, V8QImode, operands[0],
@@ -6435,9 +5712,9 @@
})
(define_expand "builtin_maxuw4"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_0_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_0_operand")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_umaxv4hi3, V4HImode, operands[0],
@@ -6446,9 +5723,9 @@
})
(define_expand "builtin_maxsw4"
- [(match_operand:DI 0 "register_operand" "")
- (match_operand:DI 1 "reg_or_0_operand" "")
- (match_operand:DI 2 "reg_or_0_operand" "")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "reg_or_0_operand")
+ (match_operand:DI 2 "reg_or_0_operand")]
"TARGET_MAX"
{
alpha_expand_builtin_vector_binop (gen_smaxv4hi3, V4HImode, operands[0],
@@ -6466,10 +5743,10 @@
[(set_attr "type" "mvi")])
(define_expand "builtin_pklb"
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(vec_concat:V8QI
(vec_concat:V4QI
- (truncate:V2QI (match_operand:DI 1 "register_operand" ""))
+ (truncate:V2QI (match_operand:DI 1 "register_operand"))
(match_dup 2))
(match_dup 3)))]
"TARGET_MAX"
@@ -6485,16 +5762,16 @@
(vec_concat:V8QI
(vec_concat:V4QI
(truncate:V2QI (match_operand:V2SI 1 "register_operand" "r"))
- (match_operand:V2QI 2 "const0_operand" ""))
- (match_operand:V4QI 3 "const0_operand" "")))]
+ (match_operand:V2QI 2 "const0_operand"))
+ (match_operand:V4QI 3 "const0_operand")))]
"TARGET_MAX"
"pklb %r1,%0"
[(set_attr "type" "mvi")])
(define_expand "builtin_pkwb"
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(vec_concat:V8QI
- (truncate:V4QI (match_operand:DI 1 "register_operand" ""))
+ (truncate:V4QI (match_operand:DI 1 "register_operand"))
(match_dup 2)))]
"TARGET_MAX"
{
@@ -6507,15 +5784,15 @@
[(set (match_operand:V8QI 0 "register_operand" "=r")
(vec_concat:V8QI
(truncate:V4QI (match_operand:V4HI 1 "register_operand" "r"))
- (match_operand:V4QI 2 "const0_operand" "")))]
+ (match_operand:V4QI 2 "const0_operand")))]
"TARGET_MAX"
"pkwb %r1,%0"
[(set_attr "type" "mvi")])
(define_expand "builtin_unpkbl"
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(zero_extend:V2SI
- (vec_select:V2QI (match_operand:DI 1 "register_operand" "")
+ (vec_select:V2QI (match_operand:DI 1 "register_operand")
(parallel [(const_int 0) (const_int 1)]))))]
"TARGET_MAX"
{
@@ -6533,9 +5810,9 @@
[(set_attr "type" "mvi")])
(define_expand "builtin_unpkbw"
- [(set (match_operand:DI 0 "register_operand" "")
+ [(set (match_operand:DI 0 "register_operand")
(zero_extend:V4HI
- (vec_select:V4QI (match_operand:DI 1 "register_operand" "")
+ (vec_select:V4QI (match_operand:DI 1 "register_operand")
(parallel [(const_int 0)
(const_int 1)
(const_int 2)
@@ -6564,9 +5841,9 @@
;; wildcard operand0 interferes with nice recognition.
(define_insn "*call_value_osf_1_er_noreturn"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(use (reg:DI 29))
(clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
@@ -6579,9 +5856,9 @@
(set_attr "length" "*,*,8")])
(define_insn "*call_value_osf_1_er"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(use (reg:DI 29))
(clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
@@ -6595,9 +5872,9 @@
;; We must use peep2 instead of a split because we need accurate life
;; information for $gp. Consider the case of { bar(); while (1); }.
(define_peephole2
- [(parallel [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand:DI 1 "call_operand" ""))
- (match_operand 2 "" "")))
+ [(parallel [(set (match_operand 0)
+ (call (mem:DI (match_operand:DI 1 "call_operand"))
+ (match_operand 2)))
(use (reg:DI 29))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
@@ -6628,9 +5905,9 @@
})
(define_peephole2
- [(parallel [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand:DI 1 "call_operand" ""))
- (match_operand 2 "" "")))
+ [(parallel [(set (match_operand 0)
+ (call (mem:DI (match_operand:DI 1 "call_operand"))
+ (match_operand 2)))
(use (reg:DI 29))
(clobber (reg:DI 26))])]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
@@ -6666,26 +5943,26 @@
})
(define_insn "*call_value_osf_2_er_nogp"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "register_operand" "c"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(use (reg:DI 29))
- (use (match_operand 3 "" ""))
- (use (match_operand 4 "" ""))
+ (use (match_operand 3))
+ (use (match_operand 4))
(clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%1),%3%J4"
[(set_attr "type" "jsr")])
(define_insn "*call_value_osf_2_er"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "register_operand" "c"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(set (reg:DI 29)
- (unspec:DI [(reg:DI 29) (match_operand 5 "const_int_operand" "")]
+ (unspec:DI [(reg:DI 29) (match_operand 5 "const_int_operand")]
UNSPEC_LDGP1))
- (use (match_operand 3 "" ""))
- (use (match_operand 4 "" ""))
+ (use (match_operand 3))
+ (use (match_operand 4))
(clobber (reg:DI 26))]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"jsr $26,(%1),%3%J4\;ldah $29,0($26)\t\t!gpdisp!%5"
@@ -6694,9 +5971,9 @@
(set_attr "length" "8")])
(define_insn "*call_value_osf_1_noreturn"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(use (reg:DI 29))
(clobber (reg:DI 26))]
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
@@ -6709,10 +5986,10 @@
(set_attr "length" "*,*,8")])
(define_insn_and_split "call_value_osf_tlsgd"
- [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand:DI 1 "symbolic_operand" ""))
+ [(set (match_operand 0)
+ (call (mem:DI (match_operand:DI 1 "symbolic_operand"))
(const_int 0)))
- (unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSGD_CALL)
+ (unspec [(match_operand:DI 2 "const_int_operand")] UNSPEC_TLSGD_CALL)
(use (reg:DI 29))
(clobber (reg:DI 26))]
"HAVE_AS_TLS"
@@ -6740,10 +6017,10 @@
[(set_attr "type" "multi")])
(define_insn_and_split "call_value_osf_tlsldm"
- [(set (match_operand 0 "" "")
- (call (mem:DI (match_operand:DI 1 "symbolic_operand" ""))
+ [(set (match_operand 0)
+ (call (mem:DI (match_operand:DI 1 "symbolic_operand"))
(const_int 0)))
- (unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSLDM_CALL)
+ (unspec [(match_operand:DI 2 "const_int_operand")] UNSPEC_TLSLDM_CALL)
(use (reg:DI 29))
(clobber (reg:DI 26))]
"HAVE_AS_TLS"
@@ -6771,9 +6048,9 @@
[(set_attr "type" "multi")])
(define_insn "*call_value_osf_1"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(use (reg:DI 29))
(clobber (reg:DI 26))]
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
@@ -6785,9 +6062,9 @@
(set_attr "length" "12,*,16")])
(define_insn "*sibcall_value_osf_1_er"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
"TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
@@ -6797,9 +6074,9 @@
(set_attr "length" "*,8")])
(define_insn "*sibcall_value_osf_1"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
"! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
"@
@@ -6812,9 +6089,9 @@
; to generate relocs for VMS link to potentially optimize the call.
; Please do not molest.
(define_insn "*call_value_vms_1"
- [(set (match_operand 0 "" "")
+ [(set (match_operand 0)
(call (mem:DI (match_operand:DI 1 "call_operand" "r,s"))
- (match_operand 2 "" "")))
+ (match_operand 2)))
(use (match_operand:DI 3 "nonmemory_operand" "r,n"))
(use (reg:DI 25))
(use (reg:DI 26))
diff --git a/gcc/config/alpha/sync.md b/gcc/config/alpha/sync.md
index bde99c456cf..cdde7256506 100644
--- a/gcc/config/alpha/sync.md
+++ b/gcc/config/alpha/sync.md
@@ -37,7 +37,7 @@
})
(define_insn "*memory_barrier"
- [(set (match_operand:BLK 0 "" "")
+ [(set (match_operand:BLK 0)
(unspec:BLK [(match_dup 0)] UNSPEC_MB))]
""
"mb"
@@ -71,18 +71,18 @@
(define_expand "atomic_compare_and_swap<mode>"
[(parallel
- [(set (match_operand:DI 0 "register_operand" "") ;; bool out
+ [(set (match_operand:DI 0 "register_operand") ;; bool out
(unspec_volatile:DI [(const_int 0)] UNSPECV_CMPXCHG))
- (set (match_operand:I48MODE 1 "register_operand" "") ;; val out
+ (set (match_operand:I48MODE 1 "register_operand") ;; val out
(unspec_volatile:I48MODE [(const_int 0)] UNSPECV_CMPXCHG))
- (set (match_operand:I48MODE 2 "memory_operand" "") ;; memory
+ (set (match_operand:I48MODE 2 "memory_operand") ;; memory
(unspec_volatile:I48MODE
[(match_dup 2)
- (match_operand:I48MODE 3 "reg_or_8bit_operand" "") ;; expected
- (match_operand:I48MODE 4 "add_operand" "") ;; desired
- (match_operand:SI 5 "const_int_operand" "") ;; is_weak
- (match_operand:SI 6 "const_int_operand" "") ;; succ model
- (match_operand:SI 7 "const_int_operand" "")] ;; fail model
+ (match_operand:I48MODE 3 "reg_or_8bit_operand") ;; expected
+ (match_operand:I48MODE 4 "add_operand") ;; desired
+ (match_operand:SI 5 "const_int_operand") ;; is_weak
+ (match_operand:SI 6 "const_int_operand") ;; succ model
+ (match_operand:SI 7 "const_int_operand")] ;; fail model
UNSPECV_CMPXCHG))])]
""
{
@@ -103,9 +103,9 @@
[(match_dup 2)
(match_operand:DI 3 "reg_or_8bit_operand" "rI") ;; expected
(match_operand:DI 4 "add_operand" "rKL") ;; desired
- (match_operand:SI 5 "const_int_operand" "") ;; is_weak
- (match_operand:SI 6 "const_int_operand" "") ;; succ model
- (match_operand:SI 7 "const_int_operand" "")] ;; fail model
+ (match_operand:SI 5 "const_int_operand") ;; is_weak
+ (match_operand:SI 6 "const_int_operand") ;; succ model
+ (match_operand:SI 7 "const_int_operand")] ;; fail model
UNSPECV_CMPXCHG))]
""
"#"
@@ -118,14 +118,14 @@
[(set_attr "type" "multi")])
(define_expand "atomic_compare_and_swap<mode>"
- [(match_operand:DI 0 "register_operand" "") ;; bool out
- (match_operand:I12MODE 1 "register_operand" "") ;; val out
- (match_operand:I12MODE 2 "mem_noofs_operand" "") ;; memory
- (match_operand:I12MODE 3 "register_operand" "") ;; expected
- (match_operand:I12MODE 4 "add_operand" "") ;; desired
- (match_operand:SI 5 "const_int_operand" "") ;; is_weak
- (match_operand:SI 6 "const_int_operand" "") ;; succ model
- (match_operand:SI 7 "const_int_operand" "")] ;; fail model
+ [(match_operand:DI 0 "register_operand") ;; bool out
+ (match_operand:I12MODE 1 "register_operand") ;; val out
+ (match_operand:I12MODE 2 "mem_noofs_operand") ;; memory
+ (match_operand:I12MODE 3 "register_operand") ;; expected
+ (match_operand:I12MODE 4 "add_operand") ;; desired
+ (match_operand:SI 5 "const_int_operand") ;; is_weak
+ (match_operand:SI 6 "const_int_operand") ;; succ model
+ (match_operand:SI 7 "const_int_operand")] ;; fail model
""
{
alpha_expand_compare_and_swap_12 (operands);
@@ -144,9 +144,9 @@
(match_operand:DI 3 "reg_or_8bit_operand" "rI") ;; expected
(match_operand:DI 4 "reg_or_0_operand" "rJ") ;; desired
(match_operand:DI 5 "register_operand" "r") ;; align
- (match_operand:SI 6 "const_int_operand" "") ;; is_weak
- (match_operand:SI 7 "const_int_operand" "") ;; succ model
- (match_operand:SI 8 "const_int_operand" "")] ;; fail model
+ (match_operand:SI 6 "const_int_operand") ;; is_weak
+ (match_operand:SI 7 "const_int_operand") ;; succ model
+ (match_operand:SI 8 "const_int_operand")] ;; fail model
UNSPECV_CMPXCHG))
(clobber (match_scratch:DI 9 "=&r"))]
""
@@ -165,7 +165,7 @@
(set (match_dup 1)
(unspec:I48MODE
[(match_operand:I48MODE 2 "add_operand" "rKL") ;; input
- (match_operand:SI 3 "const_int_operand" "")] ;; model
+ (match_operand:SI 3 "const_int_operand")] ;; model
UNSPEC_XCHG))
(clobber (match_scratch:I48MODE 4 "=&r"))]
""
@@ -179,10 +179,10 @@
[(set_attr "type" "multi")])
(define_expand "atomic_exchange<mode>"
- [(match_operand:I12MODE 0 "register_operand" "") ;; output
- (match_operand:I12MODE 1 "mem_noofs_operand" "") ;; memory
- (match_operand:I12MODE 2 "reg_or_0_operand" "") ;; input
- (match_operand:SI 3 "const_int_operand" "")] ;; model
+ [(match_operand:I12MODE 0 "register_operand") ;; output
+ (match_operand:I12MODE 1 "mem_noofs_operand") ;; memory
+ (match_operand:I12MODE 2 "reg_or_0_operand") ;; input
+ (match_operand:SI 3 "const_int_operand")] ;; model
""
{
alpha_expand_atomic_exchange_12 (operands);
@@ -197,7 +197,7 @@
(unspec:I12MODE
[(match_operand:DI 2 "reg_or_8bit_operand" "rI") ;; input
(match_operand:DI 3 "register_operand" "r") ;; align
- (match_operand:SI 4 "const_int_operand" "")] ;; model
+ (match_operand:SI 4 "const_int_operand")] ;; model
UNSPEC_XCHG))
(clobber (match_scratch:DI 5 "=&r"))]
""
@@ -215,7 +215,7 @@
(unspec:I48MODE
[(FETCHOP:I48MODE (match_dup 0)
(match_operand:I48MODE 1 "<fetchop_pred>" "<fetchop_constr>"))
- (match_operand:SI 2 "const_int_operand" "")]
+ (match_operand:SI 2 "const_int_operand")]
UNSPEC_ATOMIC))
(clobber (match_scratch:I48MODE 3 "=&r"))]
""
@@ -236,7 +236,7 @@
[(not:I48MODE
(and:I48MODE (match_dup 0)
(match_operand:I48MODE 1 "register_operand" "r")))
- (match_operand:SI 2 "const_int_operand" "")]
+ (match_operand:SI 2 "const_int_operand")]
UNSPEC_ATOMIC))
(clobber (match_scratch:I48MODE 3 "=&r"))]
""
@@ -258,7 +258,7 @@
(unspec:I48MODE
[(FETCHOP:I48MODE (match_dup 1)
(match_operand:I48MODE 2 "<fetchop_pred>" "<fetchop_constr>"))
- (match_operand:SI 3 "const_int_operand" "")]
+ (match_operand:SI 3 "const_int_operand")]
UNSPEC_ATOMIC))
(clobber (match_scratch:I48MODE 4 "=&r"))]
""
@@ -281,7 +281,7 @@
[(not:I48MODE
(and:I48MODE (match_dup 1)
(match_operand:I48MODE 2 "register_operand" "r")))
- (match_operand:SI 3 "const_int_operand" "")]
+ (match_operand:SI 3 "const_int_operand")]
UNSPEC_ATOMIC))
(clobber (match_scratch:I48MODE 4 "=&r"))]
""
@@ -304,7 +304,7 @@
(set (match_dup 1)
(unspec:I48MODE
[(FETCHOP:I48MODE (match_dup 1) (match_dup 2))
- (match_operand:SI 3 "const_int_operand" "")]
+ (match_operand:SI 3 "const_int_operand")]
UNSPEC_ATOMIC))
(clobber (match_scratch:I48MODE 4 "=&r"))]
""
@@ -327,7 +327,7 @@
(set (match_dup 1)
(unspec:I48MODE
[(not:I48MODE (and:I48MODE (match_dup 1) (match_dup 2)))
- (match_operand:SI 3 "const_int_operand" "")]
+ (match_operand:SI 3 "const_int_operand")]
UNSPEC_ATOMIC))
(clobber (match_scratch:I48MODE 4 "=&r"))]
""
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index c590ef420eb..010e7fc1c15 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -163,6 +163,7 @@ extern int arm_attr_length_push_multi(rtx, rtx);
extern void arm_expand_compare_and_swap (rtx op[]);
extern void arm_split_compare_and_swap (rtx op[]);
extern void arm_split_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx, rtx);
+extern rtx arm_load_tp (rtx);
#if defined TREE_CODE
extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 1470602a215..866385ccabb 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -753,6 +753,9 @@ int arm_arch6 = 0;
/* Nonzero if this chip supports the ARM 6K extensions. */
int arm_arch6k = 0;
+/* Nonzero if instructions present in ARMv6-M can be used. */
+int arm_arch6m = 0;
+
/* Nonzero if this chip supports the ARM 7 extensions. */
int arm_arch7 = 0;
@@ -1737,6 +1740,7 @@ arm_option_override (void)
arm_arch6 = (insn_flags & FL_ARCH6) != 0;
arm_arch6k = (insn_flags & FL_ARCH6K) != 0;
arm_arch_notm = (insn_flags & FL_NOTM) != 0;
+ arm_arch6m = arm_arch6 && !arm_arch_notm;
arm_arch7 = (insn_flags & FL_ARCH7) != 0;
arm_arch7em = (insn_flags & FL_ARCH7EM) != 0;
arm_arch_thumb2 = (insn_flags & FL_THUMB2) != 0;
@@ -6275,7 +6279,7 @@ get_tls_get_addr (void)
return tls_get_addr_libfunc;
}
-static rtx
+rtx
arm_load_tp (rtx target)
{
if (!target)
@@ -19151,8 +19155,6 @@ enum arm_builtins
ARM_BUILTIN_WMERGE,
- ARM_BUILTIN_THREAD_POINTER,
-
ARM_BUILTIN_NEON_BASE,
ARM_BUILTIN_MAX = ARM_BUILTIN_NEON_BASE + ARRAY_SIZE (neon_builtin_data)
@@ -20192,20 +20194,6 @@ arm_init_iwmmxt_builtins (void)
}
static void
-arm_init_tls_builtins (void)
-{
- tree ftype, decl;
-
- ftype = build_function_type (ptr_type_node, void_list_node);
- decl = add_builtin_function ("__builtin_thread_pointer", ftype,
- ARM_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
- NULL, NULL_TREE);
- TREE_NOTHROW (decl) = 1;
- TREE_READONLY (decl) = 1;
- arm_builtin_decls[ARM_BUILTIN_THREAD_POINTER] = decl;
-}
-
-static void
arm_init_fp16_builtins (void)
{
tree fp16_type = make_node (REAL_TYPE);
@@ -20217,8 +20205,6 @@ arm_init_fp16_builtins (void)
static void
arm_init_builtins (void)
{
- arm_init_tls_builtins ();
-
if (TARGET_REALLY_IWMMXT)
arm_init_iwmmxt_builtins ();
@@ -21330,9 +21316,6 @@ arm_expand_builtin (tree exp,
}
return arm_expand_binop_builtin (icode, exp, target);
- case ARM_BUILTIN_THREAD_POINTER:
- return arm_load_tp (target);
-
default:
break;
}
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 5f34f2a8100..34d364f00b9 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -325,7 +325,7 @@ extern void (*arm_lang_output_object_attributes_hook)(void);
#define TARGET_UNIFIED_ASM TARGET_THUMB2
/* Nonzero if this chip provides the DMB instruction. */
-#define TARGET_HAVE_DMB (arm_arch7)
+#define TARGET_HAVE_DMB (arm_arch6m || arm_arch7)
/* Nonzero if this chip implements a memory barrier via CP15. */
#define TARGET_HAVE_DMB_MCR (arm_arch6 && ! TARGET_HAVE_DMB \
@@ -470,6 +470,9 @@ extern int arm_arch6;
/* Nonzero if this chip supports the ARM Architecture 6k extensions. */
extern int arm_arch6k;
+/* Nonzero if instructions present in ARMv6-M can be used. */
+extern int arm_arch6m;
+
/* Nonzero if this chip supports the ARM Architecture 7 extensions. */
extern int arm_arch7;
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 43a9f1fef3f..b45fea02120 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -11355,6 +11355,16 @@
(set_attr "length" "4")]
)
+;; For thread pointer builtin
+(define_expand "get_thread_pointersi"
+ [(match_operand:SI 0 "s_register_operand" "=r")]
+ ""
+ "
+ {
+ arm_load_tp (operands[0]);
+ DONE;
+ }")
+
;;
;; We only care about the lower 16 bits of the constant
diff --git a/gcc/config/i386/bdver1.md b/gcc/config/i386/bdver1.md
index 2367785ff73..a43c6d075be 100644
--- a/gcc/config/i386/bdver1.md
+++ b/gcc/config/i386/bdver1.md
@@ -1,4 +1,4 @@
-;; Copyright (C) 2010, Free Software Foundation, Inc.
+;; Copyright (C) 2010, 2012 Free Software Foundation, Inc.
;;
;; This file is part of GCC.
;;
@@ -36,7 +36,7 @@
(define_attr "bdver1_decode" "direct,vector,double"
(const_string "direct"))
-(define_automaton "bdver1,bdver1_int,bdver1_load,bdver1_mult,bdver1_fp")
+(define_automaton "bdver1,bdver1_ieu,bdver1_load,bdver1_fp,bdver1_agu")
(define_cpu_unit "bdver1-decode0" "bdver1")
(define_cpu_unit "bdver1-decode1" "bdver1")
@@ -71,16 +71,14 @@
| (nothing,(bdver1-decode1 + bdver1-decode2)))")
-(define_cpu_unit "bdver1-ieu0" "bdver1_int")
-(define_cpu_unit "bdver1-ieu1" "bdver1_int")
+(define_cpu_unit "bdver1-ieu0" "bdver1_ieu")
+(define_cpu_unit "bdver1-ieu1" "bdver1_ieu")
(define_reservation "bdver1-ieu" "(bdver1-ieu0 | bdver1-ieu1)")
-(define_cpu_unit "bdver1-agu0" "bdver1_int")
-(define_cpu_unit "bdver1-agu1" "bdver1_int")
+(define_cpu_unit "bdver1-agu0" "bdver1_agu")
+(define_cpu_unit "bdver1-agu1" "bdver1_agu")
(define_reservation "bdver1-agu" "(bdver1-agu0 | bdver1-agu1)")
-(define_cpu_unit "bdver1-mult" "bdver1_mult")
-
(define_cpu_unit "bdver1-load0" "bdver1_load")
(define_cpu_unit "bdver1-load1" "bdver1_load")
(define_reservation "bdver1-load" "bdver1-agu,
@@ -93,6 +91,12 @@
;; 128bit SSE instructions issue two stores at once.
(define_reservation "bdver1-store2" "(bdver1-load0 + bdver1-load1)")
+;; vectorpath (microcoded) instructions are single issue instructions.
+;; So, they occupy all the integer units.
+(define_reservation "bdver1-ivector" "bdver1-ieu0+bdver1-ieu1+
+ bdver1-agu0+bdver1-agu1+
+ bdver1-load0+bdver1-load1")
+
;; The FP operations start to execute at stage 12 in the pipeline, while
;; integer operations start to execute at stage 9 for athlon and 11 for K8
;; Compensate the difference for athlon because it results in significantly
@@ -125,7 +129,7 @@
(define_insn_reservation "bdver1_call" 0
(and (eq_attr "cpu" "bdver1,bdver2")
(eq_attr "type" "call,callv"))
- "bdver1-double,bdver1-agu,bdver1-ieu")
+ "bdver1-double,bdver1-agu")
;; PUSH mem is double path.
(define_insn_reservation "bdver1_push" 1
(and (eq_attr "cpu" "bdver1,bdver2")
@@ -135,17 +139,17 @@
(define_insn_reservation "bdver1_pop" 1
(and (eq_attr "cpu" "bdver1,bdver2")
(eq_attr "type" "pop"))
- "bdver1-direct,(bdver1-ieu+bdver1-load)")
+ "bdver1-direct,bdver1-ivector")
;; LEAVE no latency info so far, assume same with amdfam10.
(define_insn_reservation "bdver1_leave" 3
(and (eq_attr "cpu" "bdver1,bdver2")
(eq_attr "type" "leave"))
- "bdver1-vector,(bdver1-ieu+bdver1-load)")
+ "bdver1-vector,bdver1-ivector")
;; LEA executes in AGU unit with 1 cycle latency on BDVER1.
(define_insn_reservation "bdver1_lea" 1
(and (eq_attr "cpu" "bdver1,bdver2")
(eq_attr "type" "lea"))
- "bdver1-direct,bdver1-agu,nothing")
+ "bdver1-direct,bdver1-agu")
;; MUL executes in special multiplier unit attached to IEU1.
(define_insn_reservation "bdver1_imul_DI" 6
@@ -153,23 +157,23 @@
(and (eq_attr "type" "imul")
(and (eq_attr "mode" "DI")
(eq_attr "memory" "none,unknown"))))
- "bdver1-direct1,bdver1-ieu1,bdver1-mult,nothing,bdver1-ieu1")
+ "bdver1-direct1,bdver1-ieu1")
(define_insn_reservation "bdver1_imul" 4
(and (eq_attr "cpu" "bdver1,bdver2")
(and (eq_attr "type" "imul")
(eq_attr "memory" "none,unknown")))
- "bdver1-direct1,bdver1-ieu1,bdver1-mult,bdver1-ieu1")
+ "bdver1-direct1,bdver1-ieu1")
(define_insn_reservation "bdver1_imul_mem_DI" 10
(and (eq_attr "cpu" "bdver1,bdver2")
(and (eq_attr "type" "imul")
(and (eq_attr "mode" "DI")
(eq_attr "memory" "load,both"))))
- "bdver1-direct1,bdver1-load,bdver1-ieu,bdver1-mult,nothing,bdver1-ieu")
+ "bdver1-direct1,bdver1-load,bdver1-ieu1")
(define_insn_reservation "bdver1_imul_mem" 8
(and (eq_attr "cpu" "bdver1,bdver2")
(and (eq_attr "type" "imul")
(eq_attr "memory" "load,both")))
- "bdver1-direct1,bdver1-load,bdver1-ieu,bdver1-mult,bdver1-ieu")
+ "bdver1-direct1,bdver1-load,bdver1-ieu1")
;; IDIV cannot execute in parallel with other instructions. Dealing with it
;; as with short latency vector instruction is good approximation avoiding
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 708d6bb9402..f2c5c0d1823 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -351,6 +351,8 @@ extern void mips_expand_vec_reduc (rtx, rtx, rtx (*)(rtx, rtx, rtx));
extern void mips_expand_vec_minmax (rtx, rtx, rtx,
rtx (*) (rtx, rtx, rtx), bool);
+extern rtx mips_expand_thread_pointer (rtx);
+
extern bool mips_eh_uses (unsigned int);
extern bool mips_epilogue_uses (unsigned int);
extern void mips_final_prescan_insn (rtx, rtx *, int);
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 4073a15d05d..bbd0fc429dc 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -2884,12 +2884,11 @@ mips_call_tls_get_addr (rtx sym, enum mips_symbol_type type, rtx v0)
/* Return a pseudo register that contains the current thread pointer. */
-static rtx
-mips_get_tp (void)
+rtx
+mips_expand_thread_pointer (rtx tp)
{
- rtx tp, fn;
+ rtx fn;
- tp = gen_reg_rtx (Pmode);
if (TARGET_MIPS16)
{
mips_need_mips16_rdhwr_p = true;
@@ -2904,6 +2903,12 @@ mips_get_tp (void)
return tp;
}
+static rtx
+mips_get_tp (void)
+{
+ return mips_expand_thread_pointer (gen_reg_rtx (Pmode));
+}
+
/* Generate the code to access LOC, a thread-local SYMBOL_REF, and return
its address. The return value will be both a valid address and a valid
SET_SRC (either a REG or a LO_SUM). */
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 570e7851096..c7dd87512ee 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -6880,6 +6880,16 @@
[(set_attr "type" "call")
(set_attr "length" "12")
(set_attr "mode" "<MODE>")])
+
+;; Named pattern for expanding thread pointer reference.
+(define_expand "get_thread_pointer<mode>"
+ [(match_operand:P 0 "register_operand" "=d")]
+ "HAVE_AS_TLS"
+{
+ mips_expand_thread_pointer (operands[0]);
+ DONE;
+})
+
;; Synchronization instructions.
diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c
index 26668e76da8..1ce88001277 100644
--- a/gcc/config/mmix/mmix.c
+++ b/gcc/config/mmix/mmix.c
@@ -392,15 +392,33 @@ mmix_conditional_register_usage (void)
/* INCOMING_REGNO and OUTGOING_REGNO worker function.
Those two macros must only be applied to function argument
- registers. FIXME: for their current use in gcc, it'd be better
- with an explicit specific additional FUNCTION_INCOMING_ARG_REGNO_P
- a'la TARGET_FUNCTION_ARG / TARGET_FUNCTION_INCOMING_ARG instead of
+ registers and the function return value register for the opposite
+ use. FIXME: for their current use in gcc, it'd be better with an
+ explicit specific additional FUNCTION_INCOMING_ARG_REGNO_P a'la
+ TARGET_FUNCTION_ARG / TARGET_FUNCTION_INCOMING_ARG instead of
forcing the target to commit to a fixed mapping and for any
- unspecified register use. */
+ unspecified register use. Particularly when thinking about the
+ return-value, it is better to imagine INCOMING_REGNO and
+ OUTGOING_REGNO as named CALLEE_TO_CALLER_REGNO and INNER_REGNO as
+ named CALLER_TO_CALLEE_REGNO because the direction. The "incoming"
+ and "outgoing" is from the perspective of the parameter-registers,
+ but the same macro is (must be, lacking an alternative like
+ suggested above) used to map the return-value-register from the
+ same perspective. To make directions even more confusing, the macro
+ MMIX_OUTGOING_RETURN_VALUE_REGNUM holds the number of the register
+ in which to return a value, i.e. INCOMING_REGNO for the return-value-
+ register as received from a called function; the return-value on the
+ way out. */
int
mmix_opposite_regno (int regno, int incoming)
{
+ if (incoming && regno == MMIX_OUTGOING_RETURN_VALUE_REGNUM)
+ return MMIX_RETURN_VALUE_REGNUM;
+
+ if (!incoming && regno == MMIX_RETURN_VALUE_REGNUM)
+ return MMIX_OUTGOING_RETURN_VALUE_REGNUM;
+
if (!mmix_function_arg_regno_p (regno, incoming))
return regno;
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 12b75275a32..99130ba6eef 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -490,7 +490,6 @@
(match_test "op == CONST0_RTX (mode)")))
;; Return 1 if operand is 0.0.
-;; or non-special register register field no cr0
(define_predicate "zero_fp_constant"
(and (match_code "const_double")
(match_test "SCALAR_FLOAT_MODE_P (mode)
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index 58101ab4bff..4c265665ce0 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -285,12 +285,15 @@ rs6000_define_or_undefine_macro (bool define_p, const char *name)
have both the target flags and the builtin flags as arguments. */
void
-rs6000_target_modify_macros (bool define_p, int flags, unsigned bu_mask)
+rs6000_target_modify_macros (bool define_p, HOST_WIDE_INT flags,
+ HOST_WIDE_INT bu_mask)
{
if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET)
- fprintf (stderr, "rs6000_target_modify_macros (%s, 0x%x, 0x%x)\n",
+ fprintf (stderr,
+ "rs6000_target_modify_macros (%s, " HOST_WIDE_INT_PRINT_HEX
+ ", " HOST_WIDE_INT_PRINT_HEX ")\n",
(define_p) ? "define" : "undef",
- (unsigned) flags, bu_mask);
+ flags, bu_mask);
/* target_flags based options. */
rs6000_define_or_undefine_macro (define_p, "_ARCH_PPC");
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 09c1e0ecf22..86c8250958c 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -176,7 +176,7 @@ extern void rs6000_call_indirect_aix (rtx, rtx, rtx);
extern void rs6000_aix_asm_output_dwarf_table_ref (char *);
extern void get_ppc476_thunk_name (char name[32]);
extern bool rs6000_overloaded_builtin_p (enum rs6000_builtins);
-extern unsigned rs6000_builtin_mask_calculate (void);
+extern HOST_WIDE_INT rs6000_builtin_mask_calculate (void);
/* Declare functions in rs6000-c.c */
@@ -185,8 +185,9 @@ extern void rs6000_cpu_cpp_builtins (struct cpp_reader *);
#ifdef TREE_CODE
extern bool rs6000_pragma_target_parse (tree, tree);
#endif
-extern void rs6000_target_modify_macros (bool, int, unsigned);
-extern void (*rs6000_target_modify_macros_ptr) (bool, int, unsigned);
+extern void rs6000_target_modify_macros (bool, HOST_WIDE_INT, HOST_WIDE_INT);
+extern void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT,
+ HOST_WIDE_INT);
#if TARGET_MACHO
char *output_call (rtx, rtx *, int, int);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 1384a819b1c..b6f3a9c9407 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -214,7 +214,7 @@ static GTY(()) section *toc_section;
struct builtin_description
{
- const unsigned int mask;
+ const HOST_WIDE_INT mask;
const enum insn_code icode;
const char *const name;
const enum rs6000_builtins code;
@@ -288,7 +288,7 @@ typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
/* Pointer to function (in rs6000-c.c) that can define or undefine target
macros that have changed. Languages that don't support the preprocessor
don't link in rs6000-c.c, so we can't call it directly. */
-void (*rs6000_target_modify_macros_ptr) (bool, int, unsigned);
+void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT, HOST_WIDE_INT);
/* Target cpu costs. */
@@ -894,7 +894,7 @@ struct processor_costs ppca2_cost = {
struct rs6000_builtin_info_type {
const char *name;
const enum insn_code icode;
- const unsigned mask;
+ const HOST_WIDE_INT mask;
const unsigned attr;
};
@@ -1016,6 +1016,11 @@ bool (*rs6000_cannot_change_mode_class_ptr) (enum machine_mode,
const int INSN_NOT_AVAILABLE = -1;
+static void rs6000_print_isa_options (FILE *, int, const char *,
+ HOST_WIDE_INT);
+static void rs6000_print_builtin_options (FILE *, int, const char *,
+ HOST_WIDE_INT);
+
/* Hash table stuff for keeping track of TOC entries. */
struct GTY(()) toc_hash_struct
@@ -1505,7 +1510,7 @@ struct rs6000_ptt
{
const char *const name; /* Canonical processor name. */
const enum processor_type processor; /* Processor type enum value. */
- const int target_enable; /* Target flags to enable. */
+ const HOST_WIDE_INT target_enable; /* Target flags to enable. */
};
static struct rs6000_ptt const processor_target_table[] =
@@ -1716,9 +1721,10 @@ rs6000_debug_reg_print (int first_regno, int last_regno, const char *reg_name)
}
}
-#define DEBUG_FMT_D "%-32s= %d\n"
-#define DEBUG_FMT_X "%-32s= 0x%x\n"
-#define DEBUG_FMT_S "%-32s= %s\n"
+#define DEBUG_FMT_ID "%-32s= "
+#define DEBUG_FMT_D DEBUG_FMT_ID "%d\n"
+#define DEBUG_FMT_WX DEBUG_FMT_ID "%#.12" HOST_WIDE_INT_PRINT "x: "
+#define DEBUG_FMT_S DEBUG_FMT_ID "%s\n"
/* Print various interesting information with -mdebug=reg. */
static void
@@ -1729,11 +1735,13 @@ rs6000_debug_reg_global (void)
int m;
char costly_num[20];
char nop_num[20];
+ char flags_buffer[40];
const char *costly_str;
const char *nop_str;
const char *trace_str;
const char *abi_str;
const char *cmodel_str;
+ struct cl_target_option cl_opts;
/* Map enum rs6000_vector to string. */
static const char *rs6000_debug_vector_unit[] = {
@@ -1813,12 +1821,42 @@ rs6000_debug_reg_global (void)
}
if (rs6000_cpu_index >= 0)
- fprintf (stderr, DEBUG_FMT_S, "cpu",
- processor_target_table[rs6000_cpu_index].name);
+ {
+ const char *name = processor_target_table[rs6000_cpu_index].name;
+ HOST_WIDE_INT flags
+ = processor_target_table[rs6000_cpu_index].target_enable;
+
+ sprintf (flags_buffer, "-mcpu=%s flags", name);
+ rs6000_print_isa_options (stderr, 0, flags_buffer, flags);
+ }
+ else
+ fprintf (stderr, DEBUG_FMT_S, "cpu", "<none>");
if (rs6000_tune_index >= 0)
- fprintf (stderr, DEBUG_FMT_S, "tune",
- processor_target_table[rs6000_tune_index].name);
+ {
+ const char *name = processor_target_table[rs6000_tune_index].name;
+ HOST_WIDE_INT flags
+ = processor_target_table[rs6000_tune_index].target_enable;
+
+ sprintf (flags_buffer, "-mtune=%s flags", name);
+ rs6000_print_isa_options (stderr, 0, flags_buffer, flags);
+ }
+ else
+ fprintf (stderr, DEBUG_FMT_S, "tune", "<none>");
+
+ cl_target_option_save (&cl_opts, &global_options);
+ rs6000_print_isa_options (stderr, 0, "target_flags", target_flags);
+
+ rs6000_print_isa_options (stderr, 0, "target_flags_explicit",
+ target_flags_explicit);
+
+ rs6000_print_builtin_options (stderr, 0, "rs6000_builtin_mask",
+ rs6000_builtin_mask);
+
+ rs6000_print_isa_options (stderr, 0, "TARGET_DEFAULT", TARGET_DEFAULT);
+
+ fprintf (stderr, DEBUG_FMT_S, "--with-cpu default",
+ OPTION_TARGET_CPU_DEFAULT ? OPTION_TARGET_CPU_DEFAULT : "<none>");
switch (rs6000_sched_costly_dep)
{
@@ -1936,7 +1974,15 @@ rs6000_debug_reg_global (void)
if (rs6000_float_gprs)
fprintf (stderr, DEBUG_FMT_S, "float_gprs", "true");
+ if (TARGET_LINK_STACK)
+ fprintf (stderr, DEBUG_FMT_S, "link_stack", "true");
+
+ fprintf (stderr, DEBUG_FMT_S, "plt-format",
+ TARGET_SECURE_PLT ? "secure" : "bss");
+ fprintf (stderr, DEBUG_FMT_S, "struct-return",
+ aix_struct_return ? "aix" : "sysv");
fprintf (stderr, DEBUG_FMT_S, "always_hint", tf[!!rs6000_always_hint]);
+ fprintf (stderr, DEBUG_FMT_S, "sched_groups", tf[!!rs6000_sched_groups]);
fprintf (stderr, DEBUG_FMT_S, "align_branch",
tf[!!rs6000_align_branch_targets]);
fprintf (stderr, DEBUG_FMT_D, "tls_size", rs6000_tls_size);
@@ -1948,7 +1994,6 @@ rs6000_debug_reg_global (void)
(int)END_BUILTINS);
fprintf (stderr, DEBUG_FMT_D, "Number of rs6000 builtins",
(int)RS6000_BUILTIN_COUNT);
- fprintf (stderr, DEBUG_FMT_X, "Builtin mask", rs6000_builtin_mask);
}
/* Initialize the various global tables that are based on register size. */
@@ -2354,7 +2399,7 @@ darwin_rs6000_override_options (void)
bits, and some options like SPE and PAIRED are no longer in
target_flags. */
-unsigned
+HOST_WIDE_INT
rs6000_builtin_mask_calculate (void)
{
return (((TARGET_ALTIVEC) ? RS6000_BTM_ALTIVEC : 0)
@@ -2381,7 +2426,7 @@ rs6000_option_override_internal (bool global_init_p)
/* The default cpu requested at configure time, if any. */
const char *implicit_cpu = OPTION_TARGET_CPU_DEFAULT;
- int set_masks;
+ HOST_WIDE_INT set_masks;
int cpu_index;
int tune_index;
struct cl_target_option *main_target_opt
@@ -3176,11 +3221,12 @@ rs6000_option_override_internal (bool global_init_p)
target_flags. */
rs6000_builtin_mask = rs6000_builtin_mask_calculate ();
if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET)
- fprintf (stderr, "new builtin mask = 0x%x%s%s%s%s\n", rs6000_builtin_mask,
- (rs6000_builtin_mask & RS6000_BTM_ALTIVEC) ? ", altivec" : "",
- (rs6000_builtin_mask & RS6000_BTM_VSX) ? ", vsx" : "",
- (rs6000_builtin_mask & RS6000_BTM_PAIRED) ? ", paired" : "",
- (rs6000_builtin_mask & RS6000_BTM_SPE) ? ", spe" : "");
+ {
+ fprintf (stderr,
+ "new builtin mask = " HOST_WIDE_INT_PRINT_HEX ", ",
+ rs6000_builtin_mask);
+ rs6000_print_builtin_options (stderr, 0, NULL, rs6000_builtin_mask);
+ }
/* Initialize all of the registers. */
rs6000_init_hard_regno_mode_ok (global_init_p);
@@ -6705,7 +6751,7 @@ rs6000_emit_set_const (rtx dest, enum machine_mode mode,
switch (mode)
{
- case QImode:
+ case QImode:
case HImode:
if (dest == NULL)
dest = gen_reg_rtx (mode);
@@ -10442,7 +10488,7 @@ altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
bool *expandedp)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
tree arg0, arg1, arg2;
enum machine_mode mode0, mode1;
rtx pat, op0, op1, op2;
@@ -10844,7 +10890,7 @@ static rtx
paired_expand_builtin (tree exp, rtx target, bool * expandedp)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
const struct builtin_description *d;
size_t i;
@@ -10909,7 +10955,7 @@ spe_expand_builtin (tree exp, rtx target, bool *expandedp)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
tree arg1, arg0;
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
enum insn_code icode;
enum machine_mode tmode, mode0;
rtx pat, op0;
@@ -11274,7 +11320,7 @@ rs6000_invalid_builtin (enum rs6000_builtins fncode)
{
size_t uns_fncode = (size_t)fncode;
const char *name = rs6000_builtin_info[uns_fncode].name;
- unsigned fnmask = rs6000_builtin_info[uns_fncode].mask;
+ HOST_WIDE_INT fnmask = rs6000_builtin_info[uns_fncode].mask;
gcc_assert (name != NULL);
if ((fnmask & RS6000_BTM_CELL) != 0)
@@ -11311,7 +11357,7 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
size_t i;
rtx ret;
bool success;
- unsigned mask = rs6000_builtin_info[uns_fcode].mask;
+ HOST_WIDE_INT mask = rs6000_builtin_info[uns_fcode].mask;
bool func_valid_p = ((rs6000_builtin_mask & mask) == mask);
if (TARGET_DEBUG_BUILTIN)
@@ -11694,7 +11740,7 @@ rs6000_init_builtins (void)
static tree
rs6000_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
{
- unsigned fnmask;
+ HOST_WIDE_INT fnmask;
if (code >= RS6000_BUILTIN_COUNT)
return error_mark_node;
@@ -12566,7 +12612,7 @@ rs6000_common_init_builtins (void)
tree v2si_ftype_qi = NULL_TREE;
tree v2si_ftype_v2si_qi = NULL_TREE;
tree v2si_ftype_int_qi = NULL_TREE;
- unsigned builtin_mask = rs6000_builtin_mask;
+ HOST_WIDE_INT builtin_mask = rs6000_builtin_mask;
if (!TARGET_PAIRED_FLOAT)
{
@@ -12588,7 +12634,7 @@ rs6000_common_init_builtins (void)
for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
{
tree type;
- unsigned mask = d->mask;
+ HOST_WIDE_INT mask = d->mask;
if ((mask & builtin_mask) != mask)
{
@@ -12629,7 +12675,7 @@ rs6000_common_init_builtins (void)
{
enum machine_mode mode0, mode1, mode2;
tree type;
- unsigned mask = d->mask;
+ HOST_WIDE_INT mask = d->mask;
if ((mask & builtin_mask) != mask)
{
@@ -12692,7 +12738,7 @@ rs6000_common_init_builtins (void)
{
enum machine_mode mode0, mode1;
tree type;
- unsigned mask = d->mask;
+ HOST_WIDE_INT mask = d->mask;
if ((mask & builtin_mask) != mask)
{
@@ -14944,11 +14990,10 @@ print_operand (FILE *file, rtx x, int code)
return;
case 'Q':
- if (TARGET_MFCRF)
- fputc (',', file);
- /* FALLTHRU */
- else
+ if (! TARGET_MFCRF)
return;
+ fputc (',', file);
+ /* FALLTHRU */
case 'R':
/* X is a CR register. Print the mask for `mtcrf'. */
@@ -15893,7 +15938,7 @@ rs6000_emit_cbranch (enum machine_mode mode, rtx operands[])
}
/* Return the string to output a conditional branch to LABEL, which is
- the operand number of the label, or -1 if the branch is really a
+ the operand template of the label, or NULL if the branch is really a
conditional return.
OP is the conditional expression. XEXP (OP, 0) is assumed to be a
@@ -25246,7 +25291,7 @@ rs6000_darwin_file_start (void)
{
const char *arg;
const char *name;
- int if_set;
+ HOST_WIDE_INT if_set;
} mapping[] = {
{ "ppc64", "ppc64", MASK_64BIT },
{ "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
@@ -27379,7 +27424,7 @@ rs6000_final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
struct rs6000_opt_mask {
const char *name; /* option name */
- int mask; /* mask to set */
+ HOST_WIDE_INT mask; /* mask to set */
bool invert; /* invert sense of mask */
bool valid_target; /* option is a target option */
};
@@ -27531,7 +27576,7 @@ rs6000_inner_target_options (tree args, bool attr_p)
for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
if (strcmp (r, rs6000_opt_masks[i].name) == 0)
{
- int mask = rs6000_opt_masks[i].mask;
+ HOST_WIDE_INT mask = rs6000_opt_masks[i].mask;
if (!rs6000_opt_masks[i].valid_target)
not_valid_p = true;
@@ -27755,8 +27800,8 @@ rs6000_pragma_target_parse (tree args, tree pop_target)
tree prev_tree = build_target_option_node ();
tree cur_tree;
struct cl_target_option *prev_opt, *cur_opt;
- unsigned prev_bumask, cur_bumask, diff_bumask;
- int prev_flags, cur_flags, diff_flags;
+ HOST_WIDE_INT prev_flags, cur_flags, diff_flags;
+ HOST_WIDE_INT prev_bumask, cur_bumask, diff_bumask;
if (TARGET_DEBUG_TARGET)
{
@@ -27934,37 +27979,91 @@ static void
rs6000_function_specific_print (FILE *file, int indent,
struct cl_target_option *ptr)
{
+ rs6000_print_isa_options (file, indent, "Isa options set",
+ ptr->x_target_flags);
+
+ rs6000_print_isa_options (file, indent, "Isa options explicit",
+ ptr->rs6000_target_flags_explicit);
+}
+
+/* Helper function to print the current isa or misc options on a line. */
+
+static void
+rs6000_print_options_internal (FILE *file,
+ int indent,
+ const char *string,
+ HOST_WIDE_INT flags,
+ const char *prefix,
+ const struct rs6000_opt_mask *opts,
+ size_t num_elements)
+{
size_t i;
- int flags = ptr->x_target_flags;
- unsigned bu_mask = ptr->x_rs6000_builtin_mask;
+ size_t start_column = 0;
+ size_t cur_column;
+ size_t max_column = 76;
+ const char *comma = "";
+ const char *nl = "\n";
- /* Print the various mask options. */
- for (i = 0; i < ARRAY_SIZE (rs6000_opt_masks); i++)
- if ((flags & rs6000_opt_masks[i].mask) != 0)
- {
- flags &= ~ rs6000_opt_masks[i].mask;
- fprintf (file, "%*s-m%s%s\n", indent, "",
- rs6000_opt_masks[i].invert ? "no-" : "",
- rs6000_opt_masks[i].name);
- }
+ if (indent)
+ start_column += fprintf (file, "%*s", indent, "");
- /* Print the various options that are variables. */
- for (i = 0; i < ARRAY_SIZE (rs6000_opt_vars); i++)
+ if (!flags)
{
- size_t j = rs6000_opt_vars[i].target_offset;
- if (((signed char *) ptr)[j])
- fprintf (file, "%*s-m%s\n", indent, "",
- rs6000_opt_vars[i].name);
+ fprintf (stderr, DEBUG_FMT_S, string, "<none>");
+ return;
}
- /* Print the various builtin flags. */
- fprintf (file, "%*sbuiltin mask = 0x%x\n", indent, "", bu_mask);
- for (i = 0; i < ARRAY_SIZE (rs6000_builtin_mask_names); i++)
- if ((bu_mask & rs6000_builtin_mask_names[i].mask) != 0)
- {
- fprintf (file, "%*s%s builtins supported\n", indent, "",
- rs6000_builtin_mask_names[i].name);
- }
+ start_column += fprintf (stderr, DEBUG_FMT_WX, string, flags);
+
+ /* Print the various mask options. */
+ cur_column = start_column;
+ for (i = 0; i < num_elements; i++)
+ {
+ if ((flags & opts[i].mask) != 0)
+ {
+ const char *no_str = rs6000_opt_masks[i].invert ? "no-" : "";
+ size_t len = (strlen (comma)
+ + strlen (prefix)
+ + strlen (no_str)
+ + strlen (rs6000_opt_masks[i].name));
+
+ cur_column += len;
+ if (cur_column > max_column)
+ {
+ fprintf (stderr, ", \\\n%*s", (int)start_column, "");
+ cur_column = start_column + len;
+ comma = "";
+ nl = "\n\n";
+ }
+
+ fprintf (file, "%s%s%s%s", comma, prefix, no_str,
+ rs6000_opt_masks[i].name);
+ flags &= ~ opts[i].mask;
+ comma = ", ";
+ }
+ }
+
+ fputs (nl, file);
+}
+
+/* Helper function to print the current isa options on a line. */
+
+static void
+rs6000_print_isa_options (FILE *file, int indent, const char *string,
+ HOST_WIDE_INT flags)
+{
+ rs6000_print_options_internal (file, indent, string, flags, "-m",
+ &rs6000_opt_masks[0],
+ ARRAY_SIZE (rs6000_opt_masks));
+}
+
+static void
+rs6000_print_builtin_options (FILE *file, int indent, const char *string,
+ HOST_WIDE_INT flags)
+{
+ rs6000_print_options_internal (file, indent, string, flags, "",
+ &rs6000_builtin_mask_names[0],
+ ARRAY_SIZE (rs6000_builtin_mask_names));
}
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index b968802d9fb..82388d93be8 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2229,8 +2229,7 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */
/* Define which CODE values are valid. */
-#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \
- ((CODE) == '.' || (CODE) == '&')
+#define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == '&')
/* Print a memory address as an operand to reference that memory location. */
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 4265cb67b0f..96f4f6a8321 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -266,7 +266,7 @@
; Conditional returns.
(define_code_iterator any_return [return simple_return])
(define_code_attr return_pred [(return "direct_return ()")
- (simple_return "")])
+ (simple_return "1")])
(define_code_attr return_str [(return "") (simple_return "simple_")])
; Various instructions that come in SI and DI forms.
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index 878b0fb4777..58b7694382c 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -80,7 +80,7 @@ unsigned int rs6000_recip_control
;; Mask of what builtin functions are allowed
TargetVariable
-unsigned int rs6000_builtin_mask
+HOST_WIDE_INT rs6000_builtin_mask
;; Debug flags
TargetVariable
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index a9a1af5e516..4ce1dc9542c 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -9294,132 +9294,6 @@ s390_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
return build_va_arg_indirect_ref (addr);
}
-
-/* Builtins. */
-
-enum s390_builtin
-{
- S390_BUILTIN_THREAD_POINTER,
- S390_BUILTIN_SET_THREAD_POINTER,
-
- S390_BUILTIN_max
-};
-
-static enum insn_code const code_for_builtin_64[S390_BUILTIN_max] = {
- CODE_FOR_get_tp_64,
- CODE_FOR_set_tp_64
-};
-
-static enum insn_code const code_for_builtin_31[S390_BUILTIN_max] = {
- CODE_FOR_get_tp_31,
- CODE_FOR_set_tp_31
-};
-
-static void
-s390_init_builtins (void)
-{
- tree ftype;
-
- ftype = build_function_type_list (ptr_type_node, NULL_TREE);
- add_builtin_function ("__builtin_thread_pointer", ftype,
- S390_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
- NULL, NULL_TREE);
-
- ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
- add_builtin_function ("__builtin_set_thread_pointer", ftype,
- S390_BUILTIN_SET_THREAD_POINTER, BUILT_IN_MD,
- NULL, NULL_TREE);
-}
-
-/* Expand an expression EXP that calls a built-in function,
- with result going to TARGET if that's convenient
- (and in mode MODE if that's convenient).
- SUBTARGET may be used as the target for computing one of EXP's operands.
- IGNORE is nonzero if the value is to be ignored. */
-
-static rtx
-s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED,
- int ignore ATTRIBUTE_UNUSED)
-{
-#define MAX_ARGS 2
-
- enum insn_code const *code_for_builtin =
- TARGET_64BIT ? code_for_builtin_64 : code_for_builtin_31;
-
- tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
- enum insn_code icode;
- rtx op[MAX_ARGS], pat;
- int arity;
- bool nonvoid;
- tree arg;
- call_expr_arg_iterator iter;
-
- if (fcode >= S390_BUILTIN_max)
- internal_error ("bad builtin fcode");
- icode = code_for_builtin[fcode];
- if (icode == 0)
- internal_error ("bad builtin fcode");
-
- nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
-
- arity = 0;
- FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
- {
- const struct insn_operand_data *insn_op;
-
- if (arg == error_mark_node)
- return NULL_RTX;
- if (arity > MAX_ARGS)
- return NULL_RTX;
-
- insn_op = &insn_data[icode].operand[arity + nonvoid];
-
- op[arity] = expand_expr (arg, NULL_RTX, insn_op->mode, EXPAND_NORMAL);
-
- if (!(*insn_op->predicate) (op[arity], insn_op->mode))
- op[arity] = copy_to_mode_reg (insn_op->mode, op[arity]);
- arity++;
- }
-
- if (nonvoid)
- {
- enum machine_mode tmode = insn_data[icode].operand[0].mode;
- if (!target
- || GET_MODE (target) != tmode
- || !(*insn_data[icode].operand[0].predicate) (target, tmode))
- target = gen_reg_rtx (tmode);
- }
-
- switch (arity)
- {
- case 0:
- pat = GEN_FCN (icode) (target);
- break;
- case 1:
- if (nonvoid)
- pat = GEN_FCN (icode) (target, op[0]);
- else
- pat = GEN_FCN (icode) (op[0]);
- break;
- case 2:
- pat = GEN_FCN (icode) (target, op[0], op[1]);
- break;
- default:
- gcc_unreachable ();
- }
- if (!pat)
- return NULL_RTX;
- emit_insn (pat);
-
- if (nonvoid)
- return target;
- else
- return const0_rtx;
-}
-
-
/* Output assembly code for the trampoline template to
stdio stream FILE.
@@ -11075,11 +10949,6 @@ s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY s390_return_in_memory
-#undef TARGET_INIT_BUILTINS
-#define TARGET_INIT_BUILTINS s390_init_builtins
-#undef TARGET_EXPAND_BUILTIN
-#define TARGET_EXPAND_BUILTIN s390_expand_builtin
-
#undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
#define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA s390_output_addr_const_extra
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 439d78ce4c8..efe1a470e8d 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -8710,26 +8710,15 @@
;;- Thread-local storage support.
;;
-(define_expand "get_tp_64"
- [(set (match_operand:DI 0 "nonimmediate_operand" "") (reg:DI TP_REGNUM))]
- "TARGET_64BIT"
- "")
-
-(define_expand "get_tp_31"
- [(set (match_operand:SI 0 "nonimmediate_operand" "") (reg:SI TP_REGNUM))]
- "!TARGET_64BIT"
- "")
-
-(define_expand "set_tp_64"
- [(set (reg:DI TP_REGNUM) (match_operand:DI 0 "nonimmediate_operand" ""))
- (set (reg:DI TP_REGNUM) (unspec_volatile:DI [(reg:DI TP_REGNUM)] UNSPECV_SET_TP))]
- "TARGET_64BIT"
+(define_expand "get_thread_pointer<mode>"
+ [(set (match_operand:P 0 "nonimmediate_operand" "") (reg:P TP_REGNUM))]
+ ""
"")
-(define_expand "set_tp_31"
- [(set (reg:SI TP_REGNUM) (match_operand:SI 0 "nonimmediate_operand" ""))
- (set (reg:SI TP_REGNUM) (unspec_volatile:SI [(reg:SI TP_REGNUM)] UNSPECV_SET_TP))]
- "!TARGET_64BIT"
+(define_expand "set_thread_pointer<mode>"
+ [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
+ (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
+ ""
"")
(define_insn "*set_tp"
diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md
index 89b4d0fc5a3..cd980556002 100644
--- a/gcc/config/sh/predicates.md
+++ b/gcc/config/sh/predicates.md
@@ -345,8 +345,10 @@
&& GET_MODE (op) == PSImode);
})
-;; TODO: Add a comment here.
-
+;; Returns true if OP is an operand that is either the fpul hard reg or
+;; a pseudo. This prevents combine from propagating function arguments
+;; in hard regs into insns that need the operand in fpul. If it's a pseudo
+;; reload can fix it up.
(define_predicate "fpul_operand"
(match_code "reg")
{
@@ -358,6 +360,29 @@
&& GET_MODE (op) == mode);
})
+;; Returns true if OP is a valid fpul input operand for the fsca insn.
+;; The value in fpul is a fixed-point value and its scaling is described
+;; in the fsca insn by a mult:SF. To allow pre-scaled fixed-point inputs
+;; in fpul we have to permit things like
+;; (reg:SI)
+;; (fix:SF (float:SF (reg:SI)))
+(define_predicate "fpul_fsca_operand"
+ (match_code "fix,reg")
+{
+ if (fpul_operand (op, SImode))
+ return true;
+ if (GET_CODE (op) == FIX && GET_MODE (op) == SImode
+ && GET_CODE (XEXP (op, 0)) == FLOAT && GET_MODE (XEXP (op, 0)) == SFmode)
+ return fpul_fsca_operand (XEXP (XEXP (op, 0), 0),
+ GET_MODE (XEXP (XEXP (op, 0), 0)));
+ return false;
+})
+
+;; Returns true if OP is a valid constant scale factor for the fsca insn.
+(define_predicate "fsca_scale_factor"
+ (and (match_code "const_double")
+ (match_test "op == sh_fsca_int2sf ()")))
+
;; TODO: Add a comment here.
(define_predicate "general_extend_operand"
@@ -1048,6 +1073,14 @@
}
})
+;; A predicate that returns true if OP is a valid construct around the T bit
+;; that can be used as an operand for conditional branches.
+(define_predicate "cbranch_treg_value"
+ (match_code "eq,ne,reg,subreg,xor,sign_extend,zero_extend")
+{
+ return sh_eval_treg_value (op) >= 0;
+})
+
;; Returns true of OP is arith_reg_operand or t_reg_operand.
(define_predicate "arith_reg_or_t_reg_operand"
(ior (match_operand 0 "arith_reg_operand")
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index 61d4eabfde9..f3c037cb611 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -162,6 +162,7 @@ extern bool sh_cfun_trap_exit_p (void);
extern void sh_canonicalize_comparison (enum rtx_code&, rtx&, rtx&,
enum machine_mode mode = VOIDmode);
extern rtx sh_find_equiv_gbr_addr (rtx cur_insn, rtx mem);
+extern int sh_eval_treg_value (rtx op);
#endif /* RTX_CODE */
extern void sh_cpu_cpp_builtins (cpp_reader* pfile);
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index d1ab28afd81..b617351172e 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -2059,7 +2059,7 @@ prepare_cbranch_operands (rtx *operands, enum machine_mode mode,
void
expand_cbranchsi4 (rtx *operands, enum rtx_code comparison, int probability)
{
- rtx (*branch_expander) (rtx, rtx) = gen_branch_true;
+ rtx (*branch_expander) (rtx) = gen_branch_true;
comparison = prepare_cbranch_operands (operands, SImode, comparison);
switch (comparison)
{
@@ -2071,7 +2071,7 @@ expand_cbranchsi4 (rtx *operands, enum rtx_code comparison, int probability)
emit_insn (gen_rtx_SET (VOIDmode, get_t_reg_rtx (),
gen_rtx_fmt_ee (comparison, SImode,
operands[1], operands[2])));
- rtx jump = emit_jump_insn (branch_expander (operands[3], get_t_reg_rtx ()));
+ rtx jump = emit_jump_insn (branch_expander (operands[3]));
if (probability >= 0)
add_reg_note (jump, REG_BR_PROB, GEN_INT (probability));
}
@@ -2123,7 +2123,7 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
if (TARGET_CMPEQDI_T)
{
emit_insn (gen_cmpeqdi_t (operands[1], operands[2]));
- emit_jump_insn (gen_branch_true (operands[3], get_t_reg_rtx ()));
+ emit_jump_insn (gen_branch_true (operands[3]));
return true;
}
msw_skip = NE;
@@ -2150,7 +2150,7 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
if (TARGET_CMPEQDI_T)
{
emit_insn (gen_cmpeqdi_t (operands[1], operands[2]));
- emit_jump_insn (gen_branch_false (operands[3], get_t_reg_rtx ()));
+ emit_jump_insn (gen_branch_false (operands[3]));
return true;
}
msw_taken = NE;
@@ -2281,6 +2281,43 @@ expand_cbranchdi4 (rtx *operands, enum rtx_code comparison)
return true;
}
+/* Given an operand, return 1 if the evaluated operand plugged into an
+ if_then_else will result in a branch_true, 0 if branch_false, or
+ -1 if neither nor applies. The truth table goes like this:
+
+ op | cmpval | code | result
+ ---------+--------+---------+--------------------
+ T (0) | 0 | EQ (1) | 0 = 0 ^ (0 == 1)
+ T (0) | 1 | EQ (1) | 1 = 0 ^ (1 == 1)
+ T (0) | 0 | NE (0) | 1 = 0 ^ (0 == 0)
+ T (0) | 1 | NE (0) | 0 = 0 ^ (1 == 0)
+ !T (1) | 0 | EQ (1) | 1 = 1 ^ (0 == 1)
+ !T (1) | 1 | EQ (1) | 0 = 1 ^ (1 == 1)
+ !T (1) | 0 | NE (0) | 0 = 1 ^ (0 == 0)
+ !T (1) | 1 | NE (0) | 1 = 1 ^ (1 == 0) */
+int
+sh_eval_treg_value (rtx op)
+{
+ enum rtx_code code = GET_CODE (op);
+ if ((code != EQ && code != NE) || !CONST_INT_P (XEXP (op, 1)))
+ return -1;
+
+ int cmpop = code == EQ ? 1 : 0;
+ int cmpval = INTVAL (XEXP (op, 1));
+ if (cmpval != 0 && cmpval != 1)
+ return -1;
+
+ int t;
+ if (t_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0))))
+ t = 0;
+ else if (negt_reg_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0))))
+ t = 1;
+ else
+ return -1;
+
+ return t ^ (cmpval == cmpop);
+}
+
/* Emit INSN, possibly in a PARALLEL with an USE of fpscr for SH4. */
static void
@@ -2485,9 +2522,9 @@ sh_emit_compare_and_branch (rtx *operands, enum machine_mode mode)
sh_emit_set_t_insn (gen_ieee_ccmpeqsf_t (op0, op1), mode);
if (branch_code == code)
- emit_jump_insn (gen_branch_true (operands[3], get_t_reg_rtx ()));
+ emit_jump_insn (gen_branch_true (operands[3]));
else
- emit_jump_insn (gen_branch_false (operands[3], get_t_reg_rtx ()));
+ emit_jump_insn (gen_branch_false (operands[3]));
}
void
@@ -2521,7 +2558,7 @@ sh_emit_compare_and_set (rtx *operands, enum machine_mode mode)
{
lab = gen_label_rtx ();
sh_emit_scc_to_t (EQ, op0, op1);
- emit_jump_insn (gen_branch_true (lab, get_t_reg_rtx ()));
+ emit_jump_insn (gen_branch_true (lab));
code = GT;
}
else
@@ -11778,12 +11815,6 @@ static struct builtin_description bdesc[] =
CODE_FOR_byterev, "__builtin_sh_media_BYTEREV", SH_BLTIN_2, 0 },
{ shmedia_builtin_p,
CODE_FOR_prefetch, "__builtin_sh_media_PREFO", SH_BLTIN_PSSV, 0 },
-
- { sh1_builtin_p,
- CODE_FOR_get_thread_pointer, "__builtin_thread_pointer", SH_BLTIN_VP, 0 },
- { sh1_builtin_p,
- CODE_FOR_set_thread_pointer, "__builtin_set_thread_pointer",
- SH_BLTIN_PV, 0 },
};
static void
@@ -12628,11 +12659,9 @@ check_use_sfunc_addr (rtx insn, rtx reg)
gcc_unreachable ();
}
-/* This function returns a constant rtx that represents pi / 2**15 in
- SFmode. it's used to scale SFmode angles, in radians, to a
- fixed-point signed 16.16-bit fraction of a full circle, i.e., 2*pi
- maps to 0x10000). */
-
+/* This function returns a constant rtx that represents 2**15 / pi in
+ SFmode. It's used to scale a fixed-point signed 16.16-bit fraction
+ of a full circle back to an SFmode value, i.e. 0x10000 maps to 2*pi. */
static GTY(()) rtx sh_fsca_sf2int_rtx;
rtx
@@ -12649,11 +12678,10 @@ sh_fsca_sf2int (void)
return sh_fsca_sf2int_rtx;
}
-/* This function returns a constant rtx that represents 2**15 / pi in
- SFmode. it's used to scale a fixed-point signed 16.16-bit fraction
- of a full circle back to a SFmode value, i.e., 0x10000 maps to
- 2*pi). */
-
+/* This function returns a constant rtx that represents pi / 2**15 in
+ SFmode. It's used to scale SFmode angles, in radians, to a
+ fixed-point signed 16.16-bit fraction of a full circle, i.e. 2*pi
+ maps to 0x10000. */
static GTY(()) rtx sh_fsca_int2sf_rtx;
rtx
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index a0b1e8891f8..1b6c284e388 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -541,22 +541,22 @@
(eq_attr "needs_delay_slot" "yes")
[(eq_attr "in_delay_slot" "yes") (nil) (nil)])
-;; On the SH and SH2, the rte instruction reads the return pc from the stack,
-;; and thus we can't put a pop instruction in its delay slot.
-;; On the SH3 and SH4, the rte instruction does not use the stack, so a pop
-;; instruction can go in the delay slot.
;; Since a normal return (rts) implicitly uses the PR register,
;; we can't allow PR register loads in an rts delay slot.
+;; On the SH1* and SH2*, the rte instruction reads the return pc from the
+;; stack, and thus we can't put a pop instruction in its delay slot.
+;; On the SH3* and SH4*, the rte instruction does not use the stack, so a
+;; pop instruction can go in the delay slot, unless it references a banked
+;; register (the register bank is switched by rte).
(define_delay
(eq_attr "type" "return")
[(and (eq_attr "in_delay_slot" "yes")
(ior (and (eq_attr "interrupt_function" "no")
(eq_attr "type" "!pload,prset"))
(and (eq_attr "interrupt_function" "yes")
- (ior
- (not (match_test "TARGET_SH3"))
- (eq_attr "hit_stack" "no")
- (eq_attr "banked" "no"))))) (nil) (nil)])
+ (ior (match_test "TARGET_SH3") (eq_attr "hit_stack" "no"))
+ (eq_attr "banked" "no"))))
+ (nil) (nil)])
;; Since a call implicitly uses the PR register, we can't allow
;; a PR register store in a jsr delay slot.
@@ -5322,8 +5322,8 @@ label:
emit_insn (gen_movsi (operands[0], operands[1]));
emit_jump_insn (INTVAL (operands[3])
- ? gen_branch_true (skip_neg_label, get_t_reg_rtx ())
- : gen_branch_false (skip_neg_label, get_t_reg_rtx ()));
+ ? gen_branch_true (skip_neg_label)
+ : gen_branch_false (skip_neg_label));
emit_label_after (skip_neg_label,
emit_insn (gen_negsi2 (operands[0], operands[1])));
@@ -5391,8 +5391,8 @@ label:
emit_insn (gen_movsi (high_dst, high_src));
emit_jump_insn (INTVAL (operands[3])
- ? gen_branch_true (skip_neg_label, get_t_reg_rtx ())
- : gen_branch_false (skip_neg_label, get_t_reg_rtx ()));
+ ? gen_branch_true (skip_neg_label)
+ : gen_branch_false (skip_neg_label));
if (!INTVAL (operands[3]))
emit_insn (gen_clrt ());
@@ -5575,11 +5575,57 @@ label:
[(set (match_operand:SI 0 "arith_reg_dest")
(zero_extend:SI (match_operand:QIHI 1 "zero_extend_operand")))])
-(define_insn "*zero_extend<mode>si2_compact"
+(define_insn_and_split "*zero_extend<mode>si2_compact"
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
(zero_extend:SI (match_operand:QIHI 1 "arith_reg_operand" "r")))]
"TARGET_SH1"
"extu.<bw> %1,%0"
+ "&& can_create_pseudo_p ()"
+ [(set (match_dup 0) (match_dup 2))]
+{
+ /* Sometimes combine fails to combine a T bit or negated T bit store to a
+ reg with a following zero extension. In the split pass after combine,
+ try to figure the extended reg was set. If it originated from the T
+ bit we can replace the zero extension with a reg move, which will be
+ eliminated. Notice that this also helps the *cbranch_t splitter when
+ it tries to post-combine tests and conditional branches, as it does not
+ check for zero extensions. */
+ rtx ext_reg;
+ if (REG_P (operands[1]))
+ ext_reg = operands[1];
+ else if (GET_CODE (operands[1]) == SUBREG && REG_P (SUBREG_REG (operands[1])))
+ ext_reg = SUBREG_REG (operands[1]);
+ else
+ FAIL;
+
+ /* Reg moves must be of the same mode. */
+ if (GET_MODE (ext_reg) != SImode)
+ FAIL;
+
+ operands[2] = NULL_RTX;
+ for (rtx i = prev_nonnote_insn_bb (curr_insn); i != NULL_RTX;
+ i = prev_nonnote_insn_bb (i))
+ {
+ if (LABEL_P (i) || BARRIER_P (i))
+ break;
+ if (!NONJUMP_INSN_P (i))
+ continue;
+
+ if (reg_set_p (ext_reg, i))
+ {
+ rtx set_op = XEXP (set_of (ext_reg, i), 1);
+ if (set_op == NULL_RTX)
+ break;
+ if (t_reg_operand (set_op, VOIDmode)
+ || negt_reg_operand (set_op, VOIDmode))
+ operands[2] = ext_reg;
+ break;
+ }
+ }
+
+ if (operands[2] == NULL_RTX)
+ FAIL;
+}
[(set_attr "type" "arith")])
(define_insn "*zero_extendhisi2_media"
@@ -6186,21 +6232,6 @@ label:
emit_insn (gen_ashlsi3 (operands[5], operands[0], operands[2]));
})
-;; Define additional pop for SH1 and SH2 so it does not get
-;; placed in the delay slot.
-(define_insn "*movsi_pop"
- [(set (match_operand:SI 0 "register_operand" "=r,x,l")
- (match_operand:SI 1 "sh_no_delay_pop_operand" ">,>,>"))]
- "(TARGET_SH1 || TARGET_SH2E || TARGET_SH2A)
- && ! TARGET_SH3"
- "@
- mov.l %1,%0
- lds.l %1,%0
- lds.l %1,%0"
- [(set_attr "type" "load_si,mem_mac,pload")
- (set_attr "length" "2,2,2")
- (set_attr "in_delay_slot" "no,no,no")])
-
;; t/r must come after r/r, lest reload will try to reload stuff like
;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
@@ -8108,47 +8139,126 @@ label:
;; Define the real conditional branch instructions.
;; ------------------------------------------------------------------------
-(define_insn "branch_true"
- [(set (pc) (if_then_else (ne (match_operand 1 "t_reg_operand" "")
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
+(define_expand "branch_true"
+ [(set (pc) (if_then_else (ne (reg:SI T_REG) (const_int 0))
+ (label_ref (match_operand 0))
(pc)))]
- "TARGET_SH1"
-{
- return output_branch (1, insn, operands);
-}
- [(set_attr "type" "cbranch")])
+ "TARGET_SH1")
-(define_insn "*branch_true_eq"
- [(set (pc) (if_then_else (eq (match_operand 1 "t_reg_operand" "")
- (const_int 1))
- (label_ref (match_operand 0 "" ""))
+(define_expand "branch_false"
+ [(set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
+ (label_ref (match_operand 0))
(pc)))]
- "TARGET_SH1"
-{
- return output_branch (1, insn, operands);
-}
- [(set_attr "type" "cbranch")])
+ "TARGET_SH1")
-(define_insn "branch_false"
- [(set (pc) (if_then_else (eq (match_operand 1 "t_reg_operand" "")
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
+(define_insn_and_split "*cbranch_t"
+ [(set (pc) (if_then_else (match_operand 1 "cbranch_treg_value")
+ (label_ref (match_operand 0))
(pc)))]
"TARGET_SH1"
{
- return output_branch (0, insn, operands);
+ return output_branch (sh_eval_treg_value (operands[1]), insn, operands);
}
- [(set_attr "type" "cbranch")])
-
-(define_insn "*branch_false_ne"
- [(set (pc) (if_then_else (ne (match_operand 1 "t_reg_operand" "")
- (const_int 1))
- (label_ref (match_operand 0 "" ""))
+ "&& can_create_pseudo_p ()"
+ [(set (pc) (if_then_else (eq (reg:SI T_REG) (match_dup 2))
+ (label_ref (match_dup 0))
(pc)))]
- "TARGET_SH1"
{
- return output_branch (0, insn, operands);
+ /* Try to find missed test and branch combine opportunities which result
+ in redundant T bit tests before conditional branches.
+ FIXME: Probably this would not be needed if CCmode was used
+ together with TARGET_FIXED_CONDITION_CODE_REGS. */
+
+ const int treg_value = sh_eval_treg_value (operands[1]);
+ operands[2] = NULL_RTX;
+
+ /* Scan the insns backwards for an insn that sets the T bit by testing a
+ reg against zero like:
+ (set (reg T_REG) (eq (reg) (const_int 0))) */
+ rtx testing_insn = NULL_RTX;
+ rtx tested_reg = NULL_RTX;
+
+ for (rtx i = prev_nonnote_insn_bb (curr_insn); i != NULL_RTX;
+ i = prev_nonnote_insn_bb (i))
+ {
+ if (LABEL_P (i) || BARRIER_P (i))
+ break;
+ if (!NONJUMP_INSN_P (i))
+ continue;
+
+ rtx p = PATTERN (i);
+ if (p != NULL_RTX
+ && GET_CODE (p) == SET && t_reg_operand (XEXP (p, 0), VOIDmode)
+ && GET_CODE (XEXP (p, 1)) == EQ
+ && REG_P (XEXP (XEXP (p, 1), 0))
+ && satisfies_constraint_Z (XEXP (XEXP (p, 1), 1)))
+ {
+ testing_insn = i;
+ tested_reg = XEXP (XEXP (p, 1), 0);
+ break;
+ }
+ }
+
+ if (testing_insn == NULL_RTX)
+ FAIL;
+
+ /* Continue scanning the insns backwards and try to find the insn that
+ sets the tested reg which we found above. If the reg is set by storing
+ the T bit or the negated T bit we can eliminate the test insn before
+ the branch. Notice that the branch condition has to be inverted if the
+ test is eliminated. */
+
+ /* If the T bit is used between the testing insn and the brach insn
+ leave it alone. */
+ if (reg_used_between_p (get_t_reg_rtx (), testing_insn, curr_insn))
+ FAIL;
+
+ for (rtx i = prev_nonnote_insn_bb (testing_insn); i != NULL_RTX;
+ i = prev_nonnote_insn_bb (i))
+ {
+ if (LABEL_P (i) || BARRIER_P (i))
+ break;
+ if (!NONJUMP_INSN_P (i))
+ continue;
+
+ if (reg_set_p (tested_reg, i))
+ {
+ const_rtx tested_reg_set = set_of (tested_reg, i);
+
+ /* It could also be a clobber... */
+ if (tested_reg_set == NULL_RTX || GET_CODE (tested_reg_set) != SET)
+ break;
+
+ rtx set_op1 = XEXP (tested_reg_set, 1);
+ if (t_reg_operand (set_op1, VOIDmode))
+ operands[2] = GEN_INT (treg_value ^ 1);
+ else if (negt_reg_operand (set_op1, VOIDmode))
+ operands[2] = GEN_INT (treg_value);
+ else if (REG_P (set_op1))
+ {
+ /* If it's a reg-reg copy follow the copied reg. This can
+ happen e.g. when T bit store zero-extensions are
+ eliminated. */
+ tested_reg = set_op1;
+ continue;
+ }
+
+ /* It's only safe to remove the testing insn if the T bit is not
+ modified between the testing insn and the insn that stores the
+ T bit. Notice that some T bit stores such as negc also modify
+ the T bit. */
+ if (modified_between_p (get_t_reg_rtx (), i, testing_insn)
+ || modified_in_p (get_t_reg_rtx (), i))
+ operands[2] = NULL_RTX;
+
+ break;
+ }
+ }
+
+ if (operands[2] == NULL_RTX)
+ FAIL;
+
+ set_insn_deleted (testing_insn);
}
[(set_attr "type" "cbranch")])
@@ -10085,7 +10195,7 @@ label:
;;
;; On SH the thread pointer is kept in the GBR.
;; These patterns are usually expanded from the respective built-in functions.
-(define_expand "get_thread_pointer"
+(define_expand "get_thread_pointersi"
[(set (match_operand:SI 0 "register_operand") (reg:SI GBR_REG))]
"TARGET_SH1")
@@ -10096,7 +10206,7 @@ label:
"stc gbr,%0"
[(set_attr "type" "tls_load")])
-(define_expand "set_thread_pointer"
+(define_expand "set_thread_pointersi"
[(set (reg:SI GBR_REG)
(unspec_volatile:SI [(match_operand:SI 0 "register_operand")]
UNSPECV_GBR))]
@@ -10960,25 +11070,53 @@ label:
(set (reg:SI T_REG) (const_int 1))
(use (match_dup 2))])])
-;; In some cases the zero extension does not get combined away and a
-;; sequence like the following might remain:
-;; mov #-1,r2
-;; tst r1,r1
-;; negc r2,r1
-;; extu.b r1,r1
-(define_peephole2
- [(parallel
- [(set (match_operand:SI 0 "arith_reg_dest" "")
- (xor:SI (match_operand:SI 1 "t_reg_operand" "") (const_int 1)))
- (set (reg:SI T_REG) (const_int 1))
- (use (match_operand:SI 2 "arith_reg_operand" ""))])
- (set (match_dup 0)
- (zero_extend:SI (match_operand 3 "arith_reg_operand" "")))]
- "TARGET_SH1 && REGNO (operands[0]) == REGNO (operands[3])"
- [(parallel
- [(set (match_dup 0) (xor:SI (match_dup 1) (const_int 1)))
- (set (reg:SI T_REG) (const_int 1))
- (use (match_dup 2))])])
+;; Store the negated T bit in a reg using r0 and xor. This one doesn't
+;; clobber the T bit, which is useful when storing the T bit and the
+;; negated T bit in parallel. On SH2A the movrt insn can be used for that.
+;; Usually we don't want this insn to be matched, except for cases where the
+;; T bit clobber is really not appreciated. Hence the extra use on T_REG.
+(define_insn_and_split "movrt_xor"
+ [(set (match_operand:SI 0 "arith_reg_dest" "=z")
+ (xor:SI (match_operand:SI 1 "t_reg_operand") (const_int 1)))
+ (use (reg:SI T_REG))]
+ "TARGET_SH1 && !TARGET_SH2A"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (reg:SI T_REG))
+ (set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))])
+
+;; Store the T bit and the negated T bit in two regs in parallel. There is
+;; no real insn to do that, but specifying this pattern will give combine
+;; some opportunities.
+(define_insn_and_split "*movt_movrt"
+ [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
+ (match_operand:SI 1 "negt_reg_operand"))
+ (set (match_operand:SI 2 "arith_reg_dest")
+ (match_operand:SI 3 "t_reg_operand"))])]
+ "TARGET_SH1"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ rtx i = TARGET_SH2A
+ ? gen_movrt (operands[0], get_t_reg_rtx ())
+ : gen_movrt_xor (operands[0], get_t_reg_rtx ());
+
+ emit_insn (i);
+ emit_insn (gen_movt (operands[2], get_t_reg_rtx ()));
+ DONE;
+})
+
+(define_insn_and_split "*movt_movrt"
+ [(parallel [(set (match_operand:SI 0 "arith_reg_dest")
+ (match_operand:SI 1 "t_reg_operand"))
+ (set (match_operand:SI 2 "arith_reg_dest")
+ (match_operand:SI 3 "negt_reg_operand"))])]
+ "TARGET_SH1"
+ "#"
+ "&& 1"
+ [(parallel [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 0) (match_dup 1))])])
;; Use negc to store the T bit in a MSB of a reg in the following way:
;; T = 1: 0x80000000 -> reg
@@ -12055,22 +12193,6 @@ label:
[(set_attr "type" "fsrra")
(set_attr "fp_mode" "single")])
-(define_insn "fsca"
- [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
- (vec_concat:V2SF
- (unspec:SF [(mult:SF
- (float:SF (match_operand:SI 1 "fpul_operand" "y"))
- (match_operand:SF 2 "immediate_operand" "i"))
- ] UNSPEC_FSINA)
- (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
- ] UNSPEC_FCOSA)))
- (use (match_operand:PSI 3 "fpscr_operand" "c"))]
- "TARGET_FPU_ANY && TARGET_FSCA
- && operands[2] == sh_fsca_int2sf ()"
- "fsca fpul,%d0"
- [(set_attr "type" "fsca")
- (set_attr "fp_mode" "single")])
-
;; When the sincos pattern is defined, the builtin functions sin and cos
;; will be expanded to the sincos pattern and one of the output values will
;; remain unused.
@@ -12097,6 +12219,38 @@ label:
DONE;
})
+(define_insn_and_split "fsca"
+ [(set (match_operand:V2SF 0 "fp_arith_reg_operand" "=f")
+ (vec_concat:V2SF
+ (unspec:SF [(mult:SF
+ (float:SF (match_operand:SI 1 "fpul_fsca_operand" "y"))
+ (match_operand:SF 2 "fsca_scale_factor" "i"))
+ ] UNSPEC_FSINA)
+ (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2))
+ ] UNSPEC_FCOSA)))
+ (use (match_operand:PSI 3 "fpscr_operand" "c"))]
+ "TARGET_FPU_ANY && TARGET_FSCA"
+ "fsca fpul,%d0"
+ "&& !fpul_operand (operands[1], SImode)"
+ [(const_int 0)]
+{
+ /* If operands[1] is something like (fix:SF (float:SF (reg:SI))) reduce it
+ to a simple reg, otherwise reload will have trouble reloading the
+ pseudo into fpul. */
+ rtx x = XEXP (operands[1], 0);
+ while (x != NULL_RTX && !fpul_operand (x, SImode))
+ {
+ gcc_assert (GET_CODE (x) == FIX || GET_CODE (x) == FLOAT);
+ x = XEXP (x, 0);
+ }
+
+ gcc_assert (x != NULL_RTX && fpul_operand (x, SImode));
+ emit_insn (gen_fsca (operands[0], x, operands[2], operands[3]));
+ DONE;
+}
+ [(set_attr "type" "fsca")
+ (set_attr "fp_mode" "single")])
+
(define_expand "abssf2"
[(set (match_operand:SF 0 "fp_arith_reg_operand" "")
(abs:SF (match_operand:SF 1 "fp_arith_reg_operand" "")))]
@@ -15165,7 +15319,7 @@ label:
else
{
emit_insn (gen_stack_protect_test_si (operands[0], operands[1]));
- emit_jump_insn (gen_branch_true (operands[2], get_t_reg_rtx ()));
+ emit_jump_insn (gen_branch_true (operands[2]));
}
DONE;
diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
index 83eab4b9e7a..451a074da2a 100644
--- a/gcc/config/xtensa/xtensa.c
+++ b/gcc/config/xtensa/xtensa.c
@@ -1899,7 +1899,7 @@ xtensa_legitimize_tls_address (rtx x)
case TLS_MODEL_INITIAL_EXEC:
case TLS_MODEL_LOCAL_EXEC:
tp = gen_reg_rtx (SImode);
- emit_insn (gen_load_tp (tp));
+ emit_insn (gen_get_thread_pointersi (tp));
addend = force_reg (SImode, gen_sym_TPOFF (x));
emit_insn (gen_addsi3 (dest, tp, addend));
break;
@@ -3076,8 +3076,6 @@ xtensa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
enum xtensa_builtin
{
XTENSA_BUILTIN_UMULSIDI3,
- XTENSA_BUILTIN_THREAD_POINTER,
- XTENSA_BUILTIN_SET_THREAD_POINTER,
XTENSA_BUILTIN_max
};
@@ -3096,23 +3094,6 @@ xtensa_init_builtins (void)
"__umulsidi3", NULL_TREE);
TREE_NOTHROW (decl) = 1;
TREE_READONLY (decl) = 1;
-
- if (TARGET_THREADPTR)
- {
- ftype = build_function_type_list (ptr_type_node, NULL_TREE);
- decl = add_builtin_function ("__builtin_thread_pointer", ftype,
- XTENSA_BUILTIN_THREAD_POINTER, BUILT_IN_MD,
- NULL, NULL_TREE);
- TREE_READONLY (decl) = 1;
- TREE_NOTHROW (decl) = 1;
-
- ftype = build_function_type_list (void_type_node, ptr_type_node,
- NULL_TREE);
- decl = add_builtin_function ("__builtin_set_thread_pointer", ftype,
- XTENSA_BUILTIN_SET_THREAD_POINTER,
- BUILT_IN_MD, NULL, NULL_TREE);
- TREE_NOTHROW (decl) = 1;
- }
}
@@ -3135,10 +3116,6 @@ xtensa_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *args,
fold_convert (unsigned_intDI_type_node, arg1));
break;
- case XTENSA_BUILTIN_THREAD_POINTER:
- case XTENSA_BUILTIN_SET_THREAD_POINTER:
- break;
-
default:
internal_error ("bad builtin code");
break;
@@ -3166,19 +3143,6 @@ xtensa_expand_builtin (tree exp, rtx target,
implement it. If not, just call the function. */
return expand_call (exp, target, ignore);
- case XTENSA_BUILTIN_THREAD_POINTER:
- if (!target || !register_operand (target, Pmode))
- target = gen_reg_rtx (Pmode);
- emit_insn (gen_load_tp (target));
- return target;
-
- case XTENSA_BUILTIN_SET_THREAD_POINTER:
- arg = expand_normal (CALL_EXPR_ARG (exp, 0));
- if (!register_operand (arg, Pmode))
- arg = copy_to_mode_reg (Pmode, arg);
- emit_insn (gen_set_tp (arg));
- return const0_rtx;
-
default:
internal_error ("bad builtin code");
}
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index d6eb54891b8..b87f08988ea 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -1714,7 +1714,7 @@
""
"")
-(define_insn "load_tp"
+(define_insn "get_thread_pointersi"
[(set (match_operand:SI 0 "register_operand" "=a")
(unspec:SI [(const_int 0)] UNSPEC_TP))]
"TARGET_THREADPTR"
@@ -1723,7 +1723,7 @@
(set_attr "mode" "SI")
(set_attr "length" "3")])
-(define_insn "set_tp"
+(define_insn "set_thread_pointersi"
[(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
UNSPECV_SET_TP)]
"TARGET_THREADPTR"
diff --git a/gcc/configure b/gcc/configure
index 45bba8e785e..387de5b743c 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -21237,11 +21237,15 @@ for f in $gcc_cv_as_bfd_srcdir/configure \
$gcc_cv_as_gas_srcdir/configure \
$gcc_cv_as_gas_srcdir/configure.in \
$gcc_cv_as_gas_srcdir/Makefile.in ; do
- gcc_cv_gas_version=`sed -n -e 's/^[ ]*\(VERSION=[0-9]*\.[0-9]*.*\)/\1/p' < $f`
+ gcc_cv_gas_version=`sed -n -e 's/^[ ]*VERSION=[^0-9A-Za-z_]*\([0-9]*\.[0-9]*.*\)/VERSION=\1/p' < $f`
if test x$gcc_cv_gas_version != x; then
break
fi
done
+case $gcc_cv_gas_version in
+ VERSION=[0-9]*) ;;
+ *) as_fn_error "cannot find version of in-tree assembler" "$LINENO" 5;;
+esac
gcc_cv_gas_major_version=`expr "$gcc_cv_gas_version" : "VERSION=\([0-9]*\)"`
gcc_cv_gas_minor_version=`expr "$gcc_cv_gas_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
gcc_cv_gas_patch_version=`expr "$gcc_cv_gas_version" : "VERSION=[0-9]*\.[0-9]*\.\([0-9]*\)"`
@@ -21395,11 +21399,15 @@ $as_echo "newly built ld" >&6; }
fi
for f in $gcc_cv_ld_bfd_srcdir/configure $gcc_cv_ld_gld_srcdir/configure $gcc_cv_ld_gld_srcdir/configure.in $gcc_cv_ld_gld_srcdir/Makefile.in
do
- gcc_cv_gld_version=`sed -n -e 's/^[ ]*\(VERSION=[0-9]*\.[0-9]*.*\)/\1/p' < $f`
+ gcc_cv_gld_version=`sed -n -e 's/^[ ]*VERSION=[^0-9A-Za-z_]*\([0-9]*\.[0-9]*.*\)/VERSION=\1/p' < $f`
if test x$gcc_cv_gld_version != x; then
break
fi
done
+ case $gcc_cv_gld_version in
+ VERSION=[0-9]*) ;;
+ *) as_fn_error "cannot find version of in-tree linker" "$LINENO" 5 ;;
+ esac
gcc_cv_gld_major_version=`expr "$gcc_cv_gld_version" : "VERSION=\([0-9]*\)"`
gcc_cv_gld_minor_version=`expr "$gcc_cv_gld_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
else
@@ -22063,6 +22071,12 @@ else
if test x"$ld_is_gold" = xyes; then
:
elif echo "$ld_ver" | grep GNU > /dev/null; then
+ case "${target}" in
+ mmix-knuth-mmixware)
+ # The linker emits by default mmo, not ELF, so "no" is appropriate.
+ gcc_cv_ld_hidden=no
+ ;;
+ esac
if test 0"$ld_date" -lt 20020404; then
if test -n "$ld_date"; then
# If there was date string, but was earlier than 2002-04-04, fail
@@ -22820,6 +22834,9 @@ $as_echo "$gcc_cv_as_comdat_group_percent" >&6; }
if test $gcc_cv_as_comdat_group_percent = yes; then
gcc_cv_as_comdat_group_group=no
else
+ if test -z "${gcc_cv_as_comdat_group_group+set}"; then
+ gcc_cv_as_comdat_group_group=no
+ fi
case "${target}" in
# Sun as uses a completely different syntax.
*-*-solaris2*)
@@ -25346,8 +25363,8 @@ if test "${gcc_cv_as_aix_ref+set}" = set; then :
else
gcc_cv_as_aix_ref=no
if test $in_tree_gas = yes; then
- if test $gcc_cv_gas_vers -ge `expr \( \( 2.21.0 \* 1000 \) + gcc_cv_as_aix_ref=yes \) \* 1000 + `
- then :
+ if test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 21 \) \* 1000 + 0`
+ then gcc_cv_as_aix_ref=yes
fi
elif test x$gcc_cv_as != x; then
$as_echo ' .csect stuff[rw]
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 6ad6d19c9ed..b6c049b022b 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -2049,11 +2049,17 @@ if test "$gcc_cv_ld" = ../ld/ld-new$build_exeext \
for f in $gcc_cv_ld_bfd_srcdir/configure $gcc_cv_ld_gld_srcdir/configure $gcc_cv_ld_gld_srcdir/configure.in $gcc_cv_ld_gld_srcdir/Makefile.in
do
changequote(,)dnl
- gcc_cv_gld_version=`sed -n -e 's/^[ ]*\(VERSION=[0-9]*\.[0-9]*.*\)/\1/p' < $f`
+ gcc_cv_gld_version=`sed -n -e 's/^[ ]*VERSION=[^0-9A-Za-z_]*\([0-9]*\.[0-9]*.*\)/VERSION=\1/p' < $f`
if test x$gcc_cv_gld_version != x; then
break
fi
done
+ case $gcc_cv_gld_version in
+ VERSION=[0-9]*) ;;
+changequote([,])dnl
+ *) AC_MSG_ERROR([[cannot find version of in-tree linker]]) ;;
+changequote(,)dnl
+ esac
gcc_cv_gld_major_version=`expr "$gcc_cv_gld_version" : "VERSION=\([0-9]*\)"`
gcc_cv_gld_minor_version=`expr "$gcc_cv_gld_version" : "VERSION=[0-9]*\.\([0-9]*\)"`
changequote([,])dnl
@@ -2319,6 +2325,12 @@ else
if test x"$ld_is_gold" = xyes; then
:
elif echo "$ld_ver" | grep GNU > /dev/null; then
+ case "${target}" in
+ mmix-knuth-mmixware)
+ # The linker emits by default mmo, not ELF, so "no" is appropriate.
+ gcc_cv_ld_hidden=no
+ ;;
+ esac
if test 0"$ld_date" -lt 20020404; then
if test -n "$ld_date"; then
# If there was date string, but was earlier than 2002-04-04, fail
@@ -2649,6 +2661,9 @@ else
if test $gcc_cv_as_comdat_group_percent = yes; then
gcc_cv_as_comdat_group_group=no
else
+ if test -z "${gcc_cv_as_comdat_group_group+set}"; then
+ gcc_cv_as_comdat_group_group=no
+ fi
case "${target}" in
# Sun as uses a completely different syntax.
*-*-solaris2*)
@@ -3878,7 +3893,7 @@ LCF0:
case $target in
*-*-aix*)
gcc_GAS_CHECK_FEATURE([.ref support],
- gcc_cv_as_aix_ref, [2.21.0],,
+ gcc_cv_as_aix_ref, [2,21,0],,
[ .csect stuff[[rw]]
stuff:
.long 1
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 68ebb96a7c3..5239e7e33cf 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,88 @@
+2012-10-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50080
+ * parser.c (cp_parser_optional_template_keyword): Implement
+ Core/468, allow outside template.
+
+2012-10-14 Jason Merrill <jason@redhat.com>
+ Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Implement C++11 inheriting constructors.
+ * cp-tree.h (cpp0x_warn_str): Add CPP0X_INHERITING_CTORS.
+ (DECL_INHERITED_CTOR_BASE, SET_DECL_INHERITED_CTOR_BASE): New.
+ (special_function_kind): Add sfk_inheriting_constructor.
+ * class.c (add_method): An inheriting ctor is hidden by a
+ user-declared one.
+ (one_inheriting_sig, one_inherited_ctor): New.
+ (add_implicitly_declared_members): Handle inheriting ctors.
+ * error.c (maybe_warn_cpp0x): Handle CPP0X_INHERITING_CTORS.
+ * init.c (emit_mem_initializers): Don't set LOOKUP_DEFAULTED
+ for an inheriting constructor.
+ * method.c (type_has_trivial_fn): Handle sfk_inheriting_constructor.
+ (type_set_nontrivial_flag): Likewise.
+ (add_one_base_init): Split out from...
+ (do_build_copy_constructor): ...here. Handle inheriting constructors.
+ (locate_fn_flags): Handle a list of arg types.
+ (synthesized_method_walk): Handle inheriting constructors.
+ (maybe_explain_implicit_delete): Likewise.
+ (deduce_inheriting_ctor): New.
+ (implicitly_declare_fn): Handle inheriting constructors.
+ * name-lookup.c (push_class_level_binding_1): An inheriting constructor
+ does not declare the base's name.
+ (do_class_using_decl): Allow inheriting constructors.
+ * pt.c (template_parms_to_args): Split from current_template_args.
+ (add_inherited_template_parms): New.
+ (tsubst_decl): Handle inheriting constructors.
+ * tree.c (special_function_p): Handle inheriting constructors.
+
+2012-10-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/54381
+ * semantics.c (finish_call_expr): Pass array of 3 sizeof_arg
+ trees and locs (corresponding to first 3 arguments) to
+ sizeof_pointer_memaccess_warning.
+
+2012-10-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/24449
+ * decl.c (grokfndecl): When checking for ::main declarations
+ use PROCESSING_REAL_TEMPLATE_DECL_P().
+
+2012-10-12 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/53055
+ * call.c (build_new_op_1): Pass RO_ARROW_STAR to cp_build_indirect_ref.
+ * typeck.c (cp_build_indirect_ref): Handle RO_ARROW_STAR.
+
+2012-10-11 Jason Merrill <jason@redhat.com>
+
+ * cp-tree.h (DECL_THUNKS): NULL_TREE for non-virtual functions.
+ (SET_DECL_THUNKS): New.
+ * decl.c (duplicate_decls): Adjust.
+ * method.c (make_thunk): Adjust.
+
+ * decl.c (grokdeclarator): Set DECL_GNU_TLS_P for static data
+ members, too.
+
+2012-10-09 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/53540 - using fails to be equivalent to typedef
+ * cp-tree.h (TYPE_TEMPLATE_INFO): For an alias that is not an
+ instance of alias template, don't look for its TEMPLATE_INFO in
+ its declaration.
+ (alias_template_specialization_p): Take const_tree.
+ * pt.c (alias_template_specialization_p): Take a const_tree.
+ Don't call primary_template_instantiation_p.
+ (primary_template_instantiation_p): Call
+ alias_template_specialization_p.
+
+2012-10-10 Dodji Seketeli <dodji@redhat.com>
+
+ * parser (cp_parser_statement): Parse c++11 attributes
+ tentatively.
+ (cp_parser_std_attribute_spec_seq): Do not warn too early about
+ using c++11 attributes in non c++11 mode.
+
2012-10-10 Dehao Chen <dehao@google.com>
* cp-gimplify.c (cp_genericize_r): Set location for TRY expr.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 3351a585f2b..c94bbbe3c08 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -5309,7 +5309,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
return cp_build_array_ref (input_location, arg1, arg2, complain);
case MEMBER_REF:
- return build_m_component_ref (cp_build_indirect_ref (arg1, RO_NULL,
+ return build_m_component_ref (cp_build_indirect_ref (arg1, RO_ARROW_STAR,
complain),
arg2, complain);
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 0e77b81c85b..a478de80563 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -132,7 +132,7 @@ static void finish_struct_methods (tree);
static void maybe_warn_about_overly_private_class (tree);
static int method_name_cmp (const void *, const void *);
static int resort_method_name_cmp (const void *, const void *);
-static void add_implicitly_declared_members (tree, int, int);
+static void add_implicitly_declared_members (tree, tree*, int, int);
static tree fixed_type_or_null (tree, int *, int *);
static tree build_simple_base_path (tree expr, tree binfo);
static tree build_vtbl_ref_1 (tree, tree);
@@ -1087,6 +1087,20 @@ add_method (tree type, tree method, tree using_decl)
|| same_type_p (TREE_TYPE (fn_type),
TREE_TYPE (method_type))))
{
+ if (DECL_INHERITED_CTOR_BASE (method))
+ {
+ if (DECL_INHERITED_CTOR_BASE (fn))
+ {
+ error_at (DECL_SOURCE_LOCATION (method),
+ "%q#D inherited from %qT", method,
+ DECL_INHERITED_CTOR_BASE (method));
+ error_at (DECL_SOURCE_LOCATION (fn),
+ "conflicts with version inherited from %qT",
+ DECL_INHERITED_CTOR_BASE (fn));
+ }
+ /* Otherwise defer to the other function. */
+ return false;
+ }
if (using_decl)
{
if (DECL_CONTEXT (fn) == type)
@@ -2750,6 +2764,51 @@ declare_virt_assop_and_dtor (tree t)
NULL, t);
}
+/* Declare the inheriting constructor for class T inherited from base
+ constructor CTOR with the parameter array PARMS of size NPARMS. */
+
+static void
+one_inheriting_sig (tree t, tree ctor, tree *parms, int nparms)
+{
+ /* We don't declare an inheriting ctor that would be a default,
+ copy or move ctor. */
+ if (nparms == 0
+ || (nparms == 1
+ && TREE_CODE (parms[0]) == REFERENCE_TYPE
+ && TYPE_MAIN_VARIANT (TREE_TYPE (parms[0])) == t))
+ return;
+ int i;
+ tree parmlist = void_list_node;
+ for (i = nparms - 1; i >= 0; i--)
+ parmlist = tree_cons (NULL_TREE, parms[i], parmlist);
+ tree fn = implicitly_declare_fn (sfk_inheriting_constructor,
+ t, false, ctor, parmlist);
+ if (add_method (t, fn, NULL_TREE))
+ {
+ DECL_CHAIN (fn) = TYPE_METHODS (t);
+ TYPE_METHODS (t) = fn;
+ }
+}
+
+/* Declare all the inheriting constructors for class T inherited from base
+ constructor CTOR. */
+
+static void
+one_inherited_ctor (tree ctor, tree t)
+{
+ tree parms = FUNCTION_FIRST_USER_PARMTYPE (ctor);
+
+ tree *new_parms = XALLOCAVEC (tree, list_length (parms));
+ int i = 0;
+ for (; parms && parms != void_list_node; parms = TREE_CHAIN (parms))
+ {
+ if (TREE_PURPOSE (parms))
+ one_inheriting_sig (t, ctor, new_parms, i);
+ new_parms[i++] = TREE_VALUE (parms);
+ }
+ one_inheriting_sig (t, ctor, new_parms, i);
+}
+
/* Create default constructors, assignment operators, and so forth for
the type indicated by T, if they are needed. CANT_HAVE_CONST_CTOR,
and CANT_HAVE_CONST_ASSIGNMENT are nonzero if, for whatever reason,
@@ -2758,7 +2817,7 @@ declare_virt_assop_and_dtor (tree t)
a const reference, respectively. */
static void
-add_implicitly_declared_members (tree t,
+add_implicitly_declared_members (tree t, tree* access_decls,
int cant_have_const_cctor,
int cant_have_const_assignment)
{
@@ -2826,6 +2885,26 @@ add_implicitly_declared_members (tree t,
/* We can't be lazy about declaring functions that might override
a virtual function from a base class. */
declare_virt_assop_and_dtor (t);
+
+ while (*access_decls)
+ {
+ tree using_decl = TREE_VALUE (*access_decls);
+ tree decl = USING_DECL_DECLS (using_decl);
+ if (DECL_SELF_REFERENCE_P (decl))
+ {
+ /* declare, then remove the decl */
+ tree ctor_list = CLASSTYPE_CONSTRUCTORS (TREE_TYPE (decl));
+ location_t loc = input_location;
+ input_location = DECL_SOURCE_LOCATION (using_decl);
+ if (ctor_list)
+ for (; ctor_list; ctor_list = OVL_NEXT (ctor_list))
+ one_inherited_ctor (OVL_CURRENT (ctor_list), t);
+ *access_decls = TREE_CHAIN (*access_decls);
+ input_location = loc;
+ }
+ else
+ access_decls = &TREE_CHAIN (*access_decls);
+ }
}
/* Subroutine of insert_into_classtype_sorted_fields. Recursively
@@ -4342,7 +4421,8 @@ deduce_noexcept_on_destructor (tree dtor)
{
tree ctx = DECL_CONTEXT (dtor);
tree implicit_fn = implicitly_declare_fn (sfk_destructor, ctx,
- /*const_p=*/false);
+ /*const_p=*/false,
+ NULL, NULL);
tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn));
TREE_TYPE (dtor) = build_exception_variant (TREE_TYPE (dtor), eh_spec);
}
@@ -5135,14 +5215,14 @@ check_bases_and_members (tree t)
}
/* Synthesize any needed methods. */
- add_implicitly_declared_members (t,
+ add_implicitly_declared_members (t, &access_decls,
cant_have_const_ctor,
no_const_asn_ref);
/* Check defaulted declarations here so we have cant_have_const_ctor
and don't need to worry about clones. */
for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
- if (DECL_DEFAULTED_IN_CLASS_P (fn))
+ if (!DECL_ARTIFICIAL (fn) && DECL_DEFAULTED_IN_CLASS_P (fn))
{
int copy = copy_fn_p (fn);
if (copy > 0)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 370f07230f0..7b4277b05b7 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -420,6 +420,8 @@ typedef enum cpp0x_warn_str
CPP0X_USER_DEFINED_LITERALS,
/* delegating constructors */
CPP0X_DELEGATING_CTORS,
+ /* inheriting constructors */
+ CPP0X_INHERITING_CTORS,
/* C++11 attributes */
CPP0X_ATTRIBUTES
} cpp0x_warn_str;
@@ -2378,7 +2380,20 @@ struct GTY((variable_size)) lang_decl {
/* The thunks associated with NODE, a FUNCTION_DECL. */
#define DECL_THUNKS(NODE) \
- (LANG_DECL_FN_CHECK (NODE)->context)
+ (DECL_VIRTUAL_P (NODE) ? LANG_DECL_FN_CHECK (NODE)->context : NULL_TREE)
+
+/* Set DECL_THUNKS. */
+#define SET_DECL_THUNKS(NODE,THUNKS) \
+ (LANG_DECL_FN_CHECK (NODE)->context = (THUNKS))
+
+/* If NODE, a FUNCTION_DECL, is a C++11 inheriting constructor, then this
+ is the base it inherits from. */
+#define DECL_INHERITED_CTOR_BASE(NODE) \
+ (DECL_CONSTRUCTOR_P (NODE) ? LANG_DECL_FN_CHECK (NODE)->context : NULL_TREE)
+
+/* Set the inherited base. */
+#define SET_DECL_INHERITED_CTOR_BASE(NODE,INH) \
+ (LANG_DECL_FN_CHECK (NODE)->context = (INH))
/* Nonzero if NODE is a thunk, rather than an ordinary function. */
#define DECL_THUNK_P(NODE) \
@@ -2646,8 +2661,8 @@ extern void decl_shadowed_for_var_insert (tree, tree);
template info for the alias template, not the one (if any) for the
template of the underlying type. */
#define TYPE_TEMPLATE_INFO(NODE) \
- (TYPE_ALIAS_P (NODE) \
- ? ((TYPE_NAME (NODE) && DECL_LANG_SPECIFIC (TYPE_NAME (NODE))) \
+ ((TYPE_ALIAS_P (NODE) && DECL_LANG_SPECIFIC (TYPE_NAME (NODE))) \
+ ? (DECL_LANG_SPECIFIC (TYPE_NAME (NODE)) \
? DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) \
: NULL_TREE) \
: ((TREE_CODE (NODE) == ENUMERAL_TYPE) \
@@ -4138,7 +4153,8 @@ typedef enum special_function_kind {
sfk_deleting_destructor, /* A destructor for complete objects that
deletes the object after it has been
destroyed. */
- sfk_conversion /* A conversion operator. */
+ sfk_conversion, /* A conversion operator. */
+ sfk_inheriting_constructor /* An inheriting constructor */
} special_function_kind;
/* The various kinds of linkage. From [basic.link],
@@ -5319,6 +5335,7 @@ extern void use_thunk (tree, bool);
extern bool trivial_fn_p (tree);
extern bool maybe_explain_implicit_delete (tree);
extern void explain_implicit_non_constexpr (tree);
+extern void deduce_inheriting_ctor (tree);
extern void synthesize_method (tree);
extern tree lazily_declare_fn (special_function_kind,
tree);
@@ -5331,7 +5348,7 @@ extern tree get_default_ctor (tree);
extern tree get_dtor (tree, tsubst_flags_t);
extern tree locate_ctor (tree);
extern tree implicitly_declare_fn (special_function_kind, tree,
- bool);
+ bool, tree, tree);
/* In optimize.c */
extern bool maybe_clone_body (tree);
@@ -5366,6 +5383,7 @@ extern tree maybe_update_decl_type (tree, tree);
extern bool check_default_tmpl_args (tree, tree, bool, bool, int);
extern tree push_template_decl (tree);
extern tree push_template_decl_real (tree, bool);
+extern tree add_inherited_template_parms (tree, tree);
extern bool redeclare_class_template (tree, tree);
extern tree lookup_template_class (tree, tree, tree, tree,
int, tsubst_flags_t);
@@ -5437,7 +5455,7 @@ extern bool reregister_specialization (tree, tree, tree);
extern tree fold_non_dependent_expr (tree);
extern tree fold_non_dependent_expr_sfinae (tree, tsubst_flags_t);
extern bool alias_type_or_template_p (tree);
-extern bool alias_template_specialization_p (tree);
+extern bool alias_template_specialization_p (const_tree);
extern bool explicit_class_specialization_p (tree);
extern int push_tinst_level (tree);
extern void pop_tinst_level (void);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 0b936ea1a8b..468343f40a3 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2052,7 +2052,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
/* DECL_THUNKS is only valid for virtual functions,
otherwise it is a DECL_FRIEND_CONTEXT. */
if (DECL_VIRTUAL_P (newdecl))
- DECL_THUNKS (newdecl) = DECL_THUNKS (olddecl);
+ SET_DECL_THUNKS (newdecl, DECL_THUNKS (olddecl));
}
/* Only variables have this field. */
else if (TREE_CODE (newdecl) == VAR_DECL
@@ -7416,7 +7416,7 @@ grokfndecl (tree ctype,
if (ctype == NULL_TREE && DECL_MAIN_P (decl))
{
- if (processing_template_decl)
+ if (PROCESSING_REAL_TEMPLATE_DECL_P())
error ("cannot declare %<::main%> to be a template");
if (inlinep)
error ("cannot declare %<::main%> to be inline");
@@ -10446,7 +10446,11 @@ grokdeclarator (const cp_declarator *declarator,
DECL_EXTERNAL (decl) = 1;
if (thread_p)
- DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
+ {
+ DECL_TLS_MODEL (decl) = decl_default_tls_model (decl);
+ if (declspecs->gnu_thread_keyword_p)
+ DECL_GNU_TLS_P (decl) = true;
+ }
if (constexpr_p && !initialized)
{
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 2934c9b1078..76f939f1049 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -3374,6 +3374,11 @@ maybe_warn_cpp0x (cpp0x_warn_str str)
"delegating constructors "
"only available with -std=c++11 or -std=gnu++11");
break;
+ case CPP0X_INHERITING_CTORS:
+ pedwarn (input_location, 0,
+ "inheriting constructors "
+ "only available with -std=c++11 or -std=gnu++11");
+ break;
case CPP0X_ATTRIBUTES:
pedwarn (input_location, 0,
"c++11 attributes "
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 40d0ce325f3..044603887e8 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1036,7 +1036,8 @@ emit_mem_initializers (tree mem_inits)
return;
}
- if (DECL_DEFAULTED_FN (current_function_decl))
+ if (DECL_DEFAULTED_FN (current_function_decl)
+ && ! DECL_INHERITED_CTOR_BASE (current_function_decl))
flags |= LOOKUP_DEFAULTED;
/* Sort the mem-initializers into the order in which the
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index a42ed60a99f..4da5cc9ebca 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -126,7 +126,8 @@ make_thunk (tree function, bool this_adjusting,
FUNCTION_DECL, NULL_TREE, TREE_TYPE (function));
DECL_LANG_SPECIFIC (thunk) = DECL_LANG_SPECIFIC (function);
cxx_dup_lang_specific_decl (thunk);
- DECL_THUNKS (thunk) = NULL_TREE;
+ DECL_VIRTUAL_P (thunk) = true;
+ SET_DECL_THUNKS (thunk, NULL_TREE);
DECL_CONTEXT (thunk) = DECL_CONTEXT (function);
TREE_READONLY (thunk) = TREE_READONLY (function);
@@ -157,7 +158,7 @@ make_thunk (tree function, bool this_adjusting,
/* Add it to the list of thunks associated with FUNCTION. */
DECL_CHAIN (thunk) = DECL_THUNKS (function);
- DECL_THUNKS (function) = thunk;
+ SET_DECL_THUNKS (function, thunk);
return thunk;
}
@@ -428,6 +429,8 @@ type_has_trivial_fn (tree ctype, special_function_kind sfk)
return !TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype);
case sfk_destructor:
return !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype);
+ case sfk_inheriting_constructor:
+ return false;
default:
gcc_unreachable ();
}
@@ -459,6 +462,7 @@ type_set_nontrivial_flag (tree ctype, special_function_kind sfk)
case sfk_destructor:
TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true;
return;
+ case sfk_inheriting_constructor:
default:
gcc_unreachable ();
}
@@ -477,7 +481,46 @@ trivial_fn_p (tree fn)
return type_has_trivial_fn (DECL_CONTEXT (fn), special_function_p (fn));
}
-/* Generate code for default X(X&) or X(X&&) constructor. */
+/* Subroutine of do_build_copy_constructor: Add a mem-initializer for BINFO
+ given the parameter or parameters PARM, possibly inherited constructor
+ base INH, or move flag MOVE_P. */
+
+static tree
+add_one_base_init (tree binfo, tree parm, bool move_p, tree inh,
+ tree member_init_list)
+{
+ tree init;
+ if (inh)
+ {
+ /* An inheriting constructor only has a mem-initializer for
+ the base it inherits from. */
+ if (BINFO_TYPE (binfo) != inh)
+ return member_init_list;
+
+ tree *p = &init;
+ init = NULL_TREE;
+ for (; parm; parm = DECL_CHAIN (parm))
+ {
+ tree exp = convert_from_reference (parm);
+ if (TREE_CODE (TREE_TYPE (parm)) != REFERENCE_TYPE)
+ exp = move (exp);
+ *p = build_tree_list (NULL_TREE, exp);
+ p = &TREE_CHAIN (*p);
+ }
+ }
+ else
+ {
+ init = build_base_path (PLUS_EXPR, parm, binfo, 1,
+ tf_warning_or_error);
+ if (move_p)
+ init = move (init);
+ init = build_tree_list (NULL_TREE, init);
+ }
+ return tree_cons (binfo, init, member_init_list);
+}
+
+/* Generate code for default X(X&) or X(X&&) constructor or an inheriting
+ constructor. */
static void
do_build_copy_constructor (tree fndecl)
@@ -485,8 +528,10 @@ do_build_copy_constructor (tree fndecl)
tree parm = FUNCTION_FIRST_USER_PARM (fndecl);
bool move_p = DECL_MOVE_CONSTRUCTOR_P (fndecl);
bool trivial = trivial_fn_p (fndecl);
+ tree inh = DECL_INHERITED_CTOR_BASE (fndecl);
- parm = convert_from_reference (parm);
+ if (!inh)
+ parm = convert_from_reference (parm);
if (trivial
&& is_empty_class (current_class_type))
@@ -515,14 +560,8 @@ do_build_copy_constructor (tree fndecl)
for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0;
VEC_iterate (tree, vbases, i, binfo); i++)
{
- init = build_base_path (PLUS_EXPR, parm, binfo, 1,
- tf_warning_or_error);
- if (move_p)
- init = move (init);
- member_init_list
- = tree_cons (binfo,
- build_tree_list (NULL_TREE, init),
- member_init_list);
+ member_init_list = add_one_base_init (binfo, parm, move_p, inh,
+ member_init_list);
}
for (binfo = TYPE_BINFO (current_class_type), i = 0;
@@ -530,15 +569,8 @@ do_build_copy_constructor (tree fndecl)
{
if (BINFO_VIRTUAL_P (base_binfo))
continue;
-
- init = build_base_path (PLUS_EXPR, parm, base_binfo, 1,
- tf_warning_or_error);
- if (move_p)
- init = move (init);
- member_init_list
- = tree_cons (base_binfo,
- build_tree_list (NULL_TREE, init),
- member_init_list);
+ member_init_list = add_one_base_init (base_binfo, parm, move_p,
+ inh, member_init_list);
}
for (; fields; fields = DECL_CHAIN (fields))
@@ -548,6 +580,8 @@ do_build_copy_constructor (tree fndecl)
if (TREE_CODE (field) != FIELD_DECL)
continue;
+ if (inh)
+ continue;
expr_type = TREE_TYPE (field);
if (DECL_NAME (field))
@@ -832,8 +866,23 @@ locate_fn_flags (tree type, tree name, tree argtype, int flags,
args = make_tree_vector ();
if (argtype)
{
- tree arg = build_stub_object (argtype);
- VEC_quick_push (tree, args, arg);
+ if (TREE_CODE (argtype) == TREE_LIST)
+ {
+ for (tree elt = argtype; elt != void_list_node;
+ elt = TREE_CHAIN (elt))
+ {
+ tree type = TREE_VALUE (elt);
+ if (TREE_CODE (type) != REFERENCE_TYPE)
+ type = cp_build_reference_type (type, /*rval*/true);
+ tree arg = build_stub_object (type);
+ VEC_safe_push (tree, gc, args, arg);
+ }
+ }
+ else
+ {
+ tree arg = build_stub_object (argtype);
+ VEC_quick_push (tree, args, arg);
+ }
}
fns = lookup_fnfields (binfo, name, 0);
@@ -1109,7 +1158,8 @@ walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
static void
synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
tree *spec_p, bool *trivial_p, bool *deleted_p,
- bool *constexpr_p, bool *no_implicit_p, bool diag)
+ bool *constexpr_p, bool *no_implicit_p, bool diag,
+ tree inherited_base, tree inherited_parms)
{
tree binfo, base_binfo, scope, fnname, rval, argtype;
bool move_p, copy_arg_p, assign_p, expected_trivial, check_vdtor;
@@ -1161,6 +1211,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
case sfk_constructor:
case sfk_move_constructor:
case sfk_copy_constructor:
+ case sfk_inheriting_constructor:
ctor_p = true;
fnname = complete_ctor_identifier;
break;
@@ -1169,6 +1220,9 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
gcc_unreachable ();
}
+ gcc_assert ((sfk == sfk_inheriting_constructor)
+ == (inherited_base != NULL_TREE));
+
/* If that user-written default constructor would satisfy the
requirements of a constexpr constructor (7.1.5), the
implicitly-defined default constructor is constexpr. */
@@ -1180,6 +1234,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
{
case sfk_constructor:
case sfk_destructor:
+ case sfk_inheriting_constructor:
copy_arg_p = false;
break;
@@ -1230,7 +1285,9 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
scope = push_scope (ctype);
- flags = LOOKUP_NORMAL|LOOKUP_SPECULATIVE|LOOKUP_DEFAULTED;
+ flags = LOOKUP_NORMAL|LOOKUP_SPECULATIVE;
+ if (!inherited_base)
+ flags |= LOOKUP_DEFAULTED;
complain = diag ? tf_warning_or_error : tf_none;
@@ -1251,7 +1308,11 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
if (copy_arg_p)
argtype = build_stub_type (basetype, quals, move_p);
+ else if (basetype == inherited_base)
+ argtype = inherited_parms;
rval = locate_fn_flags (base_binfo, fnname, argtype, flags, complain);
+ if (inherited_base)
+ argtype = NULL_TREE;
process_subob_fn (rval, move_p, spec_p, trivial_p, deleted_p,
constexpr_p, no_implicit_p, diag, basetype);
@@ -1404,14 +1465,16 @@ maybe_explain_implicit_delete (tree decl)
}
if (!informed)
{
- tree parm_type = TREE_VALUE (FUNCTION_FIRST_USER_PARMTYPE (decl));
+ tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
+ tree parm_type = TREE_VALUE (parms);
bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
tree scope = push_scope (ctype);
inform (0, "%q+#D is implicitly deleted because the default "
"definition would be ill-formed:", decl);
pop_scope (scope);
synthesized_method_walk (ctype, sfk, const_p,
- NULL, NULL, NULL, NULL, NULL, true);
+ NULL, NULL, NULL, NULL, NULL, true,
+ DECL_INHERITED_CTOR_BASE (decl), parms);
}
input_location = loc;
@@ -1431,7 +1494,27 @@ explain_implicit_non_constexpr (tree decl)
bool dummy;
synthesized_method_walk (DECL_CLASS_CONTEXT (decl),
special_function_p (decl), const_p,
- NULL, NULL, NULL, &dummy, NULL, true);
+ NULL, NULL, NULL, &dummy, NULL, true,
+ NULL_TREE, NULL_TREE);
+}
+
+/* DECL is an instantiation of an inheriting constructor template. Deduce
+ the correct exception-specification and deletedness for this particular
+ specialization. */
+
+void
+deduce_inheriting_ctor (tree decl)
+{
+ gcc_assert (DECL_INHERITED_CTOR_BASE (decl));
+ tree spec;
+ bool trivial, constexpr_, deleted, no_implicit;
+ synthesized_method_walk (DECL_CONTEXT (decl), sfk_inheriting_constructor,
+ false, &spec, &trivial, &deleted, &constexpr_,
+ &no_implicit, /*diag*/false,
+ DECL_INHERITED_CTOR_BASE (decl),
+ FUNCTION_FIRST_USER_PARMTYPE (decl));
+ DECL_DELETED_FN (decl) = deleted;
+ TREE_TYPE (decl) = build_exception_variant (TREE_TYPE (decl), spec);
}
/* Implicitly declare the special function indicated by KIND, as a
@@ -1441,7 +1524,9 @@ explain_implicit_non_constexpr (tree decl)
FUNCTION_DECL for the implicitly declared function. */
tree
-implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
+implicitly_declare_fn (special_function_kind kind, tree type,
+ bool const_p, tree inherited_ctor,
+ tree inherited_parms)
{
tree fn;
tree parameter_types = void_list_node;
@@ -1498,6 +1583,7 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
case sfk_copy_assignment:
case sfk_move_constructor:
case sfk_move_assignment:
+ case sfk_inheriting_constructor:
{
bool move_p;
if (kind == sfk_copy_assignment
@@ -1509,23 +1595,44 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
else
name = constructor_name (type);
- if (const_p)
- rhs_parm_type = cp_build_qualified_type (type, TYPE_QUAL_CONST);
+ if (kind == sfk_inheriting_constructor)
+ parameter_types = inherited_parms;
else
- rhs_parm_type = type;
- move_p = (kind == sfk_move_assignment
- || kind == sfk_move_constructor);
- rhs_parm_type = cp_build_reference_type (rhs_parm_type, move_p);
+ {
+ if (const_p)
+ rhs_parm_type = cp_build_qualified_type (type, TYPE_QUAL_CONST);
+ else
+ rhs_parm_type = type;
+ move_p = (kind == sfk_move_assignment
+ || kind == sfk_move_constructor);
+ rhs_parm_type = cp_build_reference_type (rhs_parm_type, move_p);
- parameter_types = tree_cons (NULL_TREE, rhs_parm_type, parameter_types);
+ parameter_types = tree_cons (NULL_TREE, rhs_parm_type, parameter_types);
+ }
break;
}
default:
gcc_unreachable ();
}
- synthesized_method_walk (type, kind, const_p, &raises, &trivial_p,
- &deleted_p, &constexpr_p, &no_implicit_p, false);
+ tree inherited_base = (inherited_ctor
+ ? DECL_CONTEXT (inherited_ctor)
+ : NULL_TREE);
+ if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL)
+ {
+ /* For an inheriting constructor template, just copy these flags from
+ the inherited constructor template for now. */
+ raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (inherited_ctor));
+ trivial_p = false;
+ deleted_p = DECL_DELETED_FN (DECL_TEMPLATE_RESULT (inherited_ctor));
+ constexpr_p
+ = DECL_DECLARED_CONSTEXPR_P (DECL_TEMPLATE_RESULT (inherited_ctor));
+ no_implicit_p = false;
+ }
+ else
+ synthesized_method_walk (type, kind, const_p, &raises, &trivial_p,
+ &deleted_p, &constexpr_p, &no_implicit_p, false,
+ inherited_base, inherited_parms);
/* Don't bother marking a deleted constructor as constexpr. */
if (deleted_p)
constexpr_p = false;
@@ -1543,9 +1650,10 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
if (raises)
fn_type = build_exception_variant (fn_type, raises);
fn = build_lang_decl (FUNCTION_DECL, name, fn_type);
- DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type));
+ if (kind != sfk_inheriting_constructor)
+ DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type));
if (kind == sfk_constructor || kind == sfk_copy_constructor
- || kind == sfk_move_constructor)
+ || kind == sfk_move_constructor || kind == sfk_inheriting_constructor)
DECL_CONSTRUCTOR_P (fn) = 1;
else if (kind == sfk_destructor)
DECL_DESTRUCTOR_P (fn) = 1;
@@ -1574,6 +1682,27 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
DECL_PARM_INDEX (decl) = DECL_PARM_LEVEL (decl) = 1;
DECL_ARGUMENTS (fn) = decl;
}
+ else if (kind == sfk_inheriting_constructor)
+ {
+ tree *p = &DECL_ARGUMENTS (fn);
+ for (tree parm = inherited_parms; parm != void_list_node;
+ parm = TREE_CHAIN (parm))
+ {
+ *p = cp_build_parm_decl (NULL_TREE, TREE_VALUE (parm));
+ DECL_CONTEXT (*p) = fn;
+ p = &DECL_CHAIN (*p);
+ }
+ SET_DECL_INHERITED_CTOR_BASE (fn, inherited_base);
+ DECL_NONCONVERTING_P (fn) = DECL_NONCONVERTING_P (inherited_ctor);
+ /* A constructor so declared has the same access as the corresponding
+ constructor in X. */
+ TREE_PRIVATE (fn) = TREE_PRIVATE (inherited_ctor);
+ TREE_PROTECTED (fn) = TREE_PROTECTED (inherited_ctor);
+ /* Copy constexpr from the inherited constructor even if the
+ inheriting constructor doesn't satisfy the requirements. */
+ constexpr_p
+ = DECL_DECLARED_CONSTEXPR_P (STRIP_TEMPLATE (inherited_ctor));
+ }
/* Add the "this" parameter. */
this_parm = build_this_parm (fn_type, TYPE_UNQUALIFIED);
DECL_CHAIN (this_parm) = DECL_ARGUMENTS (fn);
@@ -1599,6 +1728,9 @@ implicitly_declare_fn (special_function_kind kind, tree type, bool const_p)
/* Restore PROCESSING_TEMPLATE_DECL. */
processing_template_decl = saved_processing_template_decl;
+ if (inherited_ctor && TREE_CODE (inherited_ctor) == TEMPLATE_DECL)
+ fn = add_inherited_template_parms (fn, inherited_ctor);
+
return fn;
}
@@ -1612,7 +1744,8 @@ defaulted_late_check (tree fn)
tree ctx = DECL_CONTEXT (fn);
special_function_kind kind = special_function_p (fn);
bool fn_const_p = (copy_fn_p (fn) == 2);
- tree implicit_fn = implicitly_declare_fn (kind, ctx, fn_const_p);
+ tree implicit_fn = implicitly_declare_fn (kind, ctx, fn_const_p,
+ NULL, NULL);
if (!same_type_p (TREE_TYPE (TREE_TYPE (fn)),
TREE_TYPE (TREE_TYPE (implicit_fn)))
@@ -1765,7 +1898,7 @@ lazily_declare_fn (special_function_kind sfk, tree type)
}
/* Declare the function. */
- fn = implicitly_declare_fn (sfk, type, const_p);
+ fn = implicitly_declare_fn (sfk, type, const_p, NULL, NULL);
/* [class.copy]/8 If the class definition declares a move constructor or
move assignment operator, the implicitly declared copy constructor is
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index cd328b31c72..f0105604921 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3026,6 +3026,14 @@ push_class_level_binding_1 (tree name, tree x)
&& TREE_TYPE (decl) == error_mark_node)
decl = TREE_VALUE (decl);
+ if (TREE_CODE (decl) == USING_DECL
+ && TREE_CODE (USING_DECL_SCOPE (decl)) == TEMPLATE_TYPE_PARM
+ && DECL_NAME (decl) == TYPE_IDENTIFIER (USING_DECL_SCOPE (decl)))
+ /* This using-declaration declares constructors that inherit from the
+ constructors for the template parameter. It does not redeclare the
+ name of the template parameter. */
+ return true;
+
if (!check_template_shadow (decl))
return false;
@@ -3218,10 +3226,7 @@ do_class_using_decl (tree scope, tree name)
return NULL_TREE;
}
if (MAYBE_CLASS_TYPE_P (scope) && constructor_name_p (name, scope))
- {
- error ("%<%T::%D%> names constructor", scope, name);
- return NULL_TREE;
- }
+ maybe_warn_cpp0x (CPP0X_INHERITING_CTORS);
if (constructor_name_p (name, current_class_type))
{
error ("%<%T::%D%> names constructor in %qT",
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index e2b355a246f..965bc621277 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -8718,7 +8718,17 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
cp_lexer_save_tokens (parser->lexer);
attrs_location = cp_lexer_peek_token (parser->lexer)->location;
+ if (c_dialect_objc ())
+ /* In obj-c++, seing '[[' might be the either the beginning of
+ c++11 attributes, or a nested objc-message-expression. So
+ let's parse the c++11 attributes tentatively. */
+ cp_parser_parse_tentatively (parser);
std_attrs = cp_parser_std_attribute_spec_seq (parser);
+ if (c_dialect_objc ())
+ {
+ if (!cp_parser_parse_definitely (parser))
+ std_attrs = NULL_TREE;
+ }
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
@@ -20703,7 +20713,6 @@ cp_parser_std_attribute_spec (cp_parser *parser)
&& cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_OPEN_SQUARE)
{
cp_lexer_consume_token (parser->lexer);
- maybe_warn_cpp0x (CPP0X_ATTRIBUTES);
cp_lexer_consume_token (parser->lexer);
attributes = cp_parser_std_attribute_list (parser);
@@ -20711,6 +20720,10 @@ cp_parser_std_attribute_spec (cp_parser *parser)
if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE)
|| !cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
cp_parser_skip_to_end_of_statement (parser);
+ else
+ /* Warn about parsing c++11 attribute in non-c++1 mode, only
+ when we are sure that we have actually parsed them. */
+ maybe_warn_cpp0x (CPP0X_ATTRIBUTES);
}
else
{
@@ -23239,29 +23252,10 @@ cp_parser_optional_template_keyword (cp_parser *parser)
{
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
{
- /* The `template' keyword can only be used within templates;
- outside templates the parser can always figure out what is a
- template and what is not. */
- if (!processing_template_decl)
- {
- cp_token *token = cp_lexer_peek_token (parser->lexer);
- error_at (token->location,
- "%<template%> (as a disambiguator) is only allowed "
- "within templates");
- /* If this part of the token stream is rescanned, the same
- error message would be generated. So, we purge the token
- from the stream. */
- cp_lexer_purge_token (parser->lexer);
- return false;
- }
- else
- {
- /* Consume the `template' keyword. */
- cp_lexer_consume_token (parser->lexer);
- return true;
- }
+ /* Consume the `template' keyword. */
+ cp_lexer_consume_token (parser->lexer);
+ return true;
}
-
return false;
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 1377b3eed52..7e8d8b0880d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -2929,10 +2929,7 @@ primary_template_instantiation_p (const_tree t)
else if (CLASS_TYPE_P (t) && !TYPE_DECL_ALIAS_P (TYPE_NAME (t)))
return CLASSTYPE_TEMPLATE_INSTANTIATION (t)
&& PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t));
- else if (TYPE_P (t)
- && TYPE_TEMPLATE_INFO (t)
- && PRIMARY_TEMPLATE_P (TYPE_TI_TEMPLATE (t))
- && DECL_TEMPLATE_INSTANTIATION (TYPE_NAME (t)))
+ else if (alias_template_specialization_p (t))
return true;
return false;
}
@@ -3850,17 +3847,16 @@ arg_from_parm_pack_p (tree arg_pack, tree parm_pack)
return false;
}
-/* Within the declaration of a template, return all levels of template
- parameters that apply. The template parameters are represented as
- a TREE_VEC, in the form documented in cp-tree.h for template
- arguments. */
+/* Given a set of template parameters, return them as a set of template
+ arguments. The template parameters are represented as a TREE_VEC, in
+ the form documented in cp-tree.h for template arguments. */
static tree
-current_template_args (void)
+template_parms_to_args (tree parms)
{
tree header;
tree args = NULL_TREE;
- int length = TMPL_PARMS_DEPTH (current_template_parms);
+ int length = TMPL_PARMS_DEPTH (parms);
int l = length;
/* If there is only one level of template parameters, we do not
@@ -3869,7 +3865,7 @@ current_template_args (void)
if (length > 1)
args = make_tree_vec (length);
- for (header = current_template_parms; header; header = TREE_CHAIN (header))
+ for (header = parms; header; header = TREE_CHAIN (header))
{
tree a = copy_node (TREE_VALUE (header));
int i;
@@ -3906,6 +3902,15 @@ current_template_args (void)
return args;
}
+/* Within the declaration of a template, return the currently active
+ template parameters as an argument TREE_VEC. */
+
+static tree
+current_template_args (void)
+{
+ return template_parms_to_args (current_template_parms);
+}
+
/* Update the declared TYPE by doing any lookups which were thought to be
dependent, but are not now that we know the SCOPE of the declarator. */
@@ -4907,6 +4912,29 @@ push_template_decl (tree decl)
return push_template_decl_real (decl, false);
}
+/* FN is an inheriting constructor that inherits from the constructor
+ template INHERITED; turn FN into a constructor template with a matching
+ template header. */
+
+tree
+add_inherited_template_parms (tree fn, tree inherited)
+{
+ tree inner_parms
+ = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (inherited));
+ inner_parms = copy_node (inner_parms);
+ tree parms
+ = tree_cons (size_int (processing_template_decl + 1),
+ inner_parms, current_template_parms);
+ tree tmpl = build_template_decl (fn, parms, /*member*/true);
+ tree args = template_parms_to_args (parms);
+ DECL_TEMPLATE_INFO (fn) = build_template_info (tmpl, args);
+ TREE_TYPE (tmpl) = TREE_TYPE (fn);
+ DECL_TEMPLATE_RESULT (tmpl) = fn;
+ DECL_ARTIFICIAL (tmpl) = true;
+ DECL_PRIMARY_TEMPLATE (tmpl) = tmpl;
+ return tmpl;
+}
+
/* Called when a class template TYPE is redeclared with the indicated
template PARMS, e.g.:
@@ -5077,11 +5105,14 @@ alias_type_or_template_p (tree t)
/* Return TRUE iff is a specialization of an alias template. */
bool
-alias_template_specialization_p (tree t)
+alias_template_specialization_p (const_tree t)
{
if (t == NULL_TREE)
return false;
- return (primary_template_instantiation_p (t)
+
+ return (TYPE_P (t)
+ && TYPE_TEMPLATE_INFO (t)
+ && PRIMARY_TEMPLATE_P (TYPE_TI_TEMPLATE (t))
&& DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (t)));
}
@@ -10136,6 +10167,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
maybe_retrofit_in_chrg (r);
if (DECL_CONSTRUCTOR_P (r))
grok_ctor_properties (ctx, r);
+ if (DECL_INHERITED_CTOR_BASE (r))
+ deduce_inheriting_ctor (r);
/* If this is an instantiation of a member template, clone it.
If it isn't, that'll be handled by
clone_constructors_and_destructors. */
@@ -10336,9 +10369,14 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
if (DECL_DEPENDENT_P (t)
|| uses_template_parms (USING_DECL_SCOPE (t)))
{
- r = do_class_using_decl
- (tsubst_copy (USING_DECL_SCOPE (t), args, complain, in_decl),
- tsubst_copy (DECL_NAME (t), args, complain, in_decl));
+ tree scope = USING_DECL_SCOPE (t);
+ tree inst_scope = tsubst_copy (USING_DECL_SCOPE (t), args,
+ complain, in_decl);
+ tree name = tsubst_copy (DECL_NAME (t), args, complain, in_decl);
+ if (TREE_CODE (scope) == TEMPLATE_TYPE_PARM
+ && name == TYPE_IDENTIFIER (scope))
+ name = TYPE_IDENTIFIER (inst_scope);
+ r = do_class_using_decl (inst_scope, name);
if (!r)
r = error_mark_node;
else
@@ -10945,10 +10983,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
tree decl = TYPE_NAME (t);
- if (TYPE_DECL_ALIAS_P (decl)
- && DECL_LANG_SPECIFIC (decl)
- && DECL_TEMPLATE_INFO (decl)
- && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)))
+ if (alias_template_specialization_p (t))
{
/* DECL represents an alias template and we want to
instantiate it. */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 4beed0073fb..6798c1bf5d4 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2173,16 +2173,30 @@ finish_call_expr (tree fn, VEC(tree,gc) **args, bool disallow_virtual,
{
if (warn_sizeof_pointer_memaccess
&& !VEC_empty(tree, *args)
- && TREE_CODE (VEC_last(tree, *args)) == SIZEOF_EXPR
&& !processing_template_decl)
{
- tree sizeof_arg = VEC_last(tree, *args);
- if (SIZEOF_EXPR_TYPE_P (sizeof_arg))
- sizeof_arg = TREE_TYPE (TREE_OPERAND (sizeof_arg, 0));
- else
- sizeof_arg = TREE_OPERAND (sizeof_arg, 0);
+ location_t sizeof_arg_loc[3];
+ tree sizeof_arg[3];
+ unsigned int i;
+ for (i = 0; i < 3; i++)
+ {
+ tree t;
+
+ sizeof_arg_loc[i] = UNKNOWN_LOCATION;
+ sizeof_arg[i] = NULL_TREE;
+ if (i >= VEC_length (tree, *args))
+ continue;
+ t = VEC_index (tree, *args, i);
+ if (TREE_CODE (t) != SIZEOF_EXPR)
+ continue;
+ if (SIZEOF_EXPR_TYPE_P (t))
+ sizeof_arg[i] = TREE_TYPE (TREE_OPERAND (t, 0));
+ else
+ sizeof_arg[i] = TREE_OPERAND (t, 0);
+ sizeof_arg_loc[i] = EXPR_LOCATION (t);
+ }
sizeof_pointer_memaccess_warning
- (EXPR_LOCATION (VEC_last(tree, *args)), fn, *args,
+ (sizeof_arg_loc, fn, *args,
sizeof_arg, same_type_ignoring_top_level_qualifiers_p);
}
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index a41337c2116..8d555c2e2b1 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -3337,6 +3337,8 @@ special_function_p (const_tree decl)
/* Rather than doing all this stuff with magic names, we should
probably have a field of type `special_function_kind' in
DECL_LANG_SPECIFIC. */
+ if (DECL_INHERITED_CTOR_BASE (decl))
+ return sfk_inheriting_constructor;
if (DECL_COPY_CONSTRUCTOR_P (decl))
return sfk_copy_constructor;
if (DECL_MOVE_CONSTRUCTOR_P (decl))
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 13e75ab9ebf..eaa0935dc98 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2908,6 +2908,10 @@ cp_build_indirect_ref (tree ptr, ref_operator errorstring,
case RO_IMPLICIT_CONVERSION:
error ("invalid use of implicit conversion on pointer to member");
break;
+ case RO_ARROW_STAR:
+ error ("left hand operand of %<->*%> must be a pointer to class, "
+ "but is a pointer to member of type %qT", type);
+ break;
default:
gcc_unreachable ();
}
diff --git a/gcc/data-streamer-in.c b/gcc/data-streamer-in.c
index 72fce0598a7..bcd6c08a691 100644
--- a/gcc/data-streamer-in.c
+++ b/gcc/data-streamer-in.c
@@ -86,6 +86,35 @@ streamer_read_string (struct data_in *data_in, struct lto_input_block *ib)
}
+/* Read a string from the string table in DATA_IN using the bitpack BP.
+ Write the length to RLEN. */
+
+const char *
+bp_unpack_indexed_string (struct data_in *data_in,
+ struct bitpack_d *bp, unsigned int *rlen)
+{
+ return string_for_index (data_in, bp_unpack_var_len_unsigned (bp), rlen);
+}
+
+
+/* Read a NULL terminated string from the string table in DATA_IN. */
+
+const char *
+bp_unpack_string (struct data_in *data_in, struct bitpack_d *bp)
+{
+ unsigned int len;
+ const char *ptr;
+
+ ptr = bp_unpack_indexed_string (data_in, bp, &len);
+ if (!ptr)
+ return NULL;
+ if (ptr[len - 1] != '\0')
+ internal_error ("bytecode stream: found non-null terminated string");
+
+ return ptr;
+}
+
+
/* Read an unsigned HOST_WIDE_INT number from IB. */
unsigned HOST_WIDE_INT
diff --git a/gcc/data-streamer-out.c b/gcc/data-streamer-out.c
index 98cbf226176..aae4d471fb6 100644
--- a/gcc/data-streamer-out.c
+++ b/gcc/data-streamer-out.c
@@ -115,6 +115,39 @@ streamer_write_string (struct output_block *ob,
}
+/* Output STRING of LEN characters to the string table in OB. Then
+ put the index into BP.
+ When PERSISTENT is set, the string S is supposed to not change during
+ duration of the OB and thus OB can keep pointer into it. */
+
+void
+bp_pack_string_with_length (struct output_block *ob, struct bitpack_d *bp,
+ const char *s, unsigned int len, bool persistent)
+{
+ unsigned index = 0;
+ if (s)
+ index = streamer_string_index (ob, s, len, persistent);
+ bp_pack_var_len_unsigned (bp, index);
+}
+
+
+/* Output the '\0' terminated STRING to the string
+ table in OB. Then put the index onto the bitpack BP.
+ When PERSISTENT is set, the string S is supposed to not change during
+ duration of the OB and thus OB can keep pointer into it. */
+
+void
+bp_pack_string (struct output_block *ob, struct bitpack_d *bp,
+ const char *s, bool persistent)
+{
+ unsigned index = 0;
+ if (s)
+ index = streamer_string_index (ob, s, strlen (s) + 1, persistent);
+ bp_pack_var_len_unsigned (bp, index);
+}
+
+
+
/* Write a zero to the output stream. */
void
diff --git a/gcc/data-streamer.h b/gcc/data-streamer.h
index c413a75930f..705713cd1bd 100644
--- a/gcc/data-streamer.h
+++ b/gcc/data-streamer.h
@@ -72,6 +72,10 @@ unsigned streamer_string_index (struct output_block *, const char *,
void streamer_write_string_with_length (struct output_block *,
struct lto_output_stream *,
const char *, unsigned int, bool);
+void bp_pack_string_with_length (struct output_block *, struct bitpack_d *,
+ const char *, unsigned int, bool);
+void bp_pack_string (struct output_block *, struct bitpack_d *,
+ const char *, bool);
void streamer_write_uhwi_stream (struct lto_output_stream *,
unsigned HOST_WIDE_INT);
void streamer_write_hwi_stream (struct lto_output_stream *, HOST_WIDE_INT);
@@ -82,6 +86,9 @@ const char *streamer_read_string (struct data_in *, struct lto_input_block *);
const char *streamer_read_indexed_string (struct data_in *,
struct lto_input_block *,
unsigned int *);
+const char *bp_unpack_indexed_string (struct data_in *, struct bitpack_d *,
+ unsigned int *);
+const char *bp_unpack_string (struct data_in *, struct bitpack_d *);
unsigned HOST_WIDE_INT streamer_read_uhwi (struct lto_input_block *);
HOST_WIDE_INT streamer_read_hwi (struct lto_input_block *);
diff --git a/gcc/df-problems.c b/gcc/df-problems.c
index 53e77388f02..b4df2ba2a14 100644
--- a/gcc/df-problems.c
+++ b/gcc/df-problems.c
@@ -57,42 +57,6 @@ along with GCC; see the file COPYING3. If not see
static bitmap_head seen_in_block;
static bitmap_head seen_in_insn;
-
-/*----------------------------------------------------------------------------
- Public functions access functions for the dataflow problems.
-----------------------------------------------------------------------------*/
-/* Get the live at out set for BB no matter what problem happens to be
- defined. This function is used by the register allocators who
- choose different dataflow problems depending on the optimization
- level. */
-
-bitmap
-df_get_live_out (basic_block bb)
-{
- gcc_assert (df_lr);
-
- if (df_live)
- return DF_LIVE_OUT (bb);
- else
- return DF_LR_OUT (bb);
-}
-
-/* Get the live at in set for BB no matter what problem happens to be
- defined. This function is used by the register allocators who
- choose different dataflow problems depending on the optimization
- level. */
-
-bitmap
-df_get_live_in (basic_block bb)
-{
- gcc_assert (df_lr);
-
- if (df_live)
- return DF_LIVE_IN (bb);
- else
- return DF_LR_IN (bb);
-}
-
/*----------------------------------------------------------------------------
Utility functions.
----------------------------------------------------------------------------*/
diff --git a/gcc/df.h b/gcc/df.h
index e7031d0bb2f..c0902b16d7a 100644
--- a/gcc/df.h
+++ b/gcc/df.h
@@ -951,8 +951,6 @@ extern void debug_df_chain (struct df_link *);
extern struct df_link *df_chain_create (df_ref, df_ref);
extern void df_chain_unlink (df_ref);
extern void df_chain_copy (df_ref, struct df_link *);
-extern bitmap df_get_live_in (basic_block);
-extern bitmap df_get_live_out (basic_block);
extern void df_grow_bb_info (struct dataflow *);
extern void df_chain_dump (struct df_link *, FILE *);
extern void df_print_bb_index (basic_block bb, FILE *file);
@@ -1023,7 +1021,10 @@ extern void df_compute_regs_ever_live (bool);
extern bool df_read_modify_subreg_p (rtx);
extern void df_scan_verify (void);
-/* Get basic block info. */
+
+/*----------------------------------------------------------------------------
+ Public functions access functions for the dataflow problems.
+----------------------------------------------------------------------------*/
static inline struct df_scan_bb_info *
df_scan_get_bb_info (unsigned int index)
@@ -1079,6 +1080,39 @@ df_word_lr_get_bb_info (unsigned int index)
return NULL;
}
+/* Get the live at out set for BB no matter what problem happens to be
+ defined. This function is used by the register allocators who
+ choose different dataflow problems depending on the optimization
+ level. */
+
+static inline bitmap
+df_get_live_out (basic_block bb)
+{
+ gcc_checking_assert (df_lr);
+
+ if (df_live)
+ return DF_LIVE_OUT (bb);
+ else
+ return DF_LR_OUT (bb);
+}
+
+/* Get the live at in set for BB no matter what problem happens to be
+ defined. This function is used by the register allocators who
+ choose different dataflow problems depending on the optimization
+ level. */
+
+static inline bitmap
+df_get_live_in (basic_block bb)
+{
+ gcc_checking_assert (df_lr);
+
+ if (df_live)
+ return DF_LIVE_IN (bb);
+ else
+ return DF_LR_IN (bb);
+}
+
+/* Get basic block info. */
/* Get the artificial defs for a basic block. */
static inline df_ref *
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 9fd2f27b0fd..a07539a4adb 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -6864,7 +6864,7 @@ a1, @dots{}, an@} >> @{b0, b1, @dots{}, bn@} == @{a0 >> b0, a1 >> b1,
@dots{}, an >> bn@}}@. Vector operands must have the same number of
elements.
-For the convenience in C it is allowed to use a binary vector operation
+For convenience, it is allowed to use a binary vector operation
where one operand is a scalar. In that case the compiler will transform
the scalar operand into a vector where each element is the scalar from
the operation. The transformation will happen only if the scalar could be
diff --git a/gcc/doc/generic.texi b/gcc/doc/generic.texi
index c48b663a033..082a5282c8d 100644
--- a/gcc/doc/generic.texi
+++ b/gcc/doc/generic.texi
@@ -1388,7 +1388,8 @@ shift. Right shift should be treated as arithmetic, i.e., the
high-order bits should be zero-filled when the expression has unsigned
type and filled with the sign bit when the expression has signed type.
Note that the result is undefined if the second operand is larger
-than or equal to the first operand's type size.
+than or equal to the first operand's type size. Unlike most nodes, these
+can have a vector as first operand and a scalar as second operand.
@item BIT_IOR_EXPR
@@ -1482,11 +1483,12 @@ allows the backend to choose between the faster of @code{TRUNC_DIV_EXPR},
@itemx NE_EXPR
These nodes represent the less than, less than or equal to, greater
than, greater than or equal to, equal, and not equal comparison
-operators. The first and second operand with either be both of integral
-type or both of floating type. The result type of these expressions
-will always be of integral or boolean type. These operations return
-the result type's zero value for false, and the result type's one value
-for true.
+operators. The first and second operands will either be both of integral
+type, both of floating type or both of vector type. The result type of
+these expressions will always be of integral, boolean or signed integral
+vector type. These operations return the result type's zero value for
+false, the result type's one value for true, and a vector whose elements
+are zero (false) or minus one (true) for vectors.
For floating point comparisons, if we honor IEEE NaNs and either operand
is NaN, then @code{NE_EXPR} always returns true and the remaining operators
@@ -1769,6 +1771,17 @@ of elements of a floating point type. The result is a vector that contains
twice as many elements of an integral type whose size is half as wide. The
elements of the two vectors are merged (concatenated) to form the output
vector.
+
+@item VEC_COND_EXPR
+These nodes represent @code{?:} expressions. The three operands must be
+vectors of the same size and number of elements. The second and third
+operands must have the same type as the entire expression. The first
+operand is of signed integral vector type. If an element of the first
+operand evaluates to a zero value, the corresponding element of the
+result is taken from the third operand. If it evaluates to a minus one
+value, it is taken from the second operand. It should never evaluate to
+any other value. In contrast with a @code{COND_EXPR}, all operands are
+always evaluated.
@end table
diff --git a/gcc/doc/gty.texi b/gcc/doc/gty.texi
index b2214b8053b..ea1a928c4ab 100644
--- a/gcc/doc/gty.texi
+++ b/gcc/doc/gty.texi
@@ -65,6 +65,27 @@ The parser understands simple typedefs such as
@code{typedef int @var{name};}.
These don't need to be marked.
+Since @code{gengtype}'s understanding of C++ is limited, there are
+several constructs and declarations that are not supported inside
+classes/structures marked for automatic GC code generation. The
+following C++ constructs produce a @code{gengtype} error on
+structures/classes marked for automatic GC code generation:
+
+@itemize @bullet
+@item
+Type definitions inside classes/structures are not supported.
+@item
+Enumerations inside classes/structures are not supported.
+@end itemize
+
+If you have a class or structure using any of the above constructs,
+you need to mark that class as @code{GTY ((user))} and provide your
+own marking routines (see section @ref{User GC} for details).
+
+It is always valid to include function definitions inside classes.
+Those are always ignored by @code{gengtype}, as it only cares about
+data members.
+
@menu
* GTY Options:: What goes inside a @code{GTY(())}.
* GGC Roots:: Making global variables GGC roots.
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 9f2012f148a..6a1db6ad607 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -665,6 +665,22 @@ as follows, having the output control string start with a @samp{@@}:
@end group
@end smallexample
+If you just need a little bit of C code in one (or a few) alternatives,
+you can use @samp{*} inside of a @samp{@@} multi-alternative template:
+
+@smallexample
+@group
+(define_insn ""
+ [(set (match_operand:SI 0 "general_operand" "=r,<,m")
+ (const_int 0))]
+ ""
+ "@@
+ clrreg %0
+ * return stack_mem_p (operands[0]) ? \"push 0\" : \"clrmem %0\";
+ clrmem %0")
+@end group
+@end smallexample
+
@node Predicates
@section Predicates
@cindex predicates
@@ -6133,6 +6149,18 @@ If this pattern is not specified, all memory models except
@code{__ATOMIC_RELAXED} will result in issuing a @code{sync_synchronize}
barrier pattern.
+@cindex @code{get_thread_pointer@var{mode}} instruction pattern
+@cindex @code{set_thread_pointer@var{mode}} instruction pattern
+@item @samp{get_thread_pointer@var{mode}}
+@itemx @samp{set_thread_pointer@var{mode}}
+These patterns emit code that reads/sets the TLS thread pointer. Currently,
+these are only needed if the target needs to support the
+@code{__builtin_thread_pointer} and @code{__builtin_set_thread_pointer}
+builtins.
+
+The get/set patterns have a single output/input operand respectively,
+with @var{mode} intended to be @code{Pmode}.
+
@cindex @code{stack_protect_set} instruction pattern
@item @samp{stack_protect_set}
diff --git a/gcc/expr.c b/gcc/expr.c
index 1adea93c316..7cf812d3e3a 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -10270,10 +10270,15 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
{
enum insn_code icode;
- op0 = copy_rtx (op0);
-
if (TYPE_ALIGN_OK (type))
- set_mem_align (op0, MAX (MEM_ALIGN (op0), TYPE_ALIGN (type)));
+ {
+ /* ??? Copying the MEM without substantially changing it might
+ run afoul of the code handling volatile memory references in
+ store_expr, which assumes that TARGET is returned unmodified
+ if it has been used. */
+ op0 = copy_rtx (op0);
+ set_mem_align (op0, MAX (MEM_ALIGN (op0), TYPE_ALIGN (type)));
+ }
else if (mode != BLKmode
&& MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode)
/* If the target does have special handling for unaligned
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 99655a1df9c..b1d811d3548 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -8294,6 +8294,40 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
return build_vector (type, elts);
}
+ case REDUC_MIN_EXPR:
+ case REDUC_MAX_EXPR:
+ case REDUC_PLUS_EXPR:
+ {
+ unsigned int nelts = TYPE_VECTOR_SUBPARTS (type), i;
+ tree *elts;
+ enum tree_code subcode;
+
+ if (TREE_CODE (op0) != VECTOR_CST)
+ return NULL_TREE;
+
+ elts = XALLOCAVEC (tree, nelts);
+ if (!vec_cst_ctor_to_array (op0, elts))
+ return NULL_TREE;
+
+ switch (code)
+ {
+ case REDUC_MIN_EXPR: subcode = MIN_EXPR; break;
+ case REDUC_MAX_EXPR: subcode = MAX_EXPR; break;
+ case REDUC_PLUS_EXPR: subcode = PLUS_EXPR; break;
+ default: gcc_unreachable ();
+ }
+
+ for (i = 1; i < nelts; i++)
+ {
+ elts[0] = const_binop (subcode, elts[0], elts[i]);
+ if (elts[0] == NULL_TREE || !CONSTANT_CLASS_P (elts[0]))
+ return NULL_TREE;
+ elts[i] = build_zero_cst (TREE_TYPE (type));
+ }
+
+ return build_vector (type, elts);
+ }
+
default:
return NULL_TREE;
} /* switch (code) */
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 7a3092a420c..ad701865927 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,15 @@
+2012-10-12 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/40453
+ * interface.c (check_dummy_characteristics): Recursively check dummy
+ procedures.
+
+2012-10-11 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/54784
+ * trans-stmt.c (gfc_trans_allocate): Correctly determine the reference
+ to the _data component for polymorphic allocation with SOURCE.
+
2012-10-06 Janus Weil <janus@gcc.gnu.org>
PR fortran/54832
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index 4822149cc0b..2bdabfe806c 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -1063,6 +1063,19 @@ check_dummy_characteristics (gfc_symbol *s1, gfc_symbol *s2,
/* FIXME: Do more comprehensive testing of attributes, like e.g.
ASYNCHRONOUS, CONTIGUOUS, VALUE, VOLATILE, etc. */
+ /* Check interface of dummy procedures. */
+ if (s1->attr.flavor == FL_PROCEDURE)
+ {
+ char err[200];
+ if (!gfc_compare_interfaces (s1, s2, s2->name, 0, 1, err, sizeof(err),
+ NULL, NULL))
+ {
+ snprintf (errmsg, err_len, "Interface mismatch in dummy procedure "
+ "'%s': %s", s1->name, err);
+ return FAILURE;
+ }
+ }
+
/* Check string length. */
if (s1->ts.type == BT_CHARACTER
&& s1->ts.u.cl && s1->ts.u.cl->length
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 204f069cc53..bfcb6869baa 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -5130,7 +5130,7 @@ gfc_trans_allocate (gfc_code * code)
gfc_actual_arglist *actual;
gfc_expr *ppc;
gfc_code *ppc_code;
- gfc_ref *dataref;
+ gfc_ref *ref, *dataref;
/* Do a polymorphic deep copy. */
actual = gfc_get_actual_arglist ();
@@ -5142,13 +5142,15 @@ gfc_trans_allocate (gfc_code * code)
actual->next->expr->ts.type = BT_CLASS;
gfc_add_data_component (actual->next->expr);
- dataref = actual->next->expr->ref;
+ dataref = NULL;
/* Make sure we go up through the reference chain to
the _data reference, where the arrayspec is found. */
- while (dataref->next && dataref->next->type != REF_ARRAY)
- dataref = dataref->next;
+ for (ref = actual->next->expr->ref; ref; ref = ref->next)
+ if (ref->type == REF_COMPONENT
+ && strcmp (ref->u.c.component->name, "_data") == 0)
+ dataref = ref;
- if (dataref->u.c.component->as)
+ if (dataref && dataref->u.c.component->as)
{
int dim;
gfc_expr *temp;
diff --git a/gcc/gcov.c b/gcc/gcov.c
index cf26ce19a2c..09831c2c6d6 100644
--- a/gcc/gcov.c
+++ b/gcc/gcov.c
@@ -842,7 +842,7 @@ create_file_names (const char *file_name)
}
/* Remove the extension. */
- cptr = strrchr (name, '.');
+ cptr = strrchr (CONST_CAST (char *, lbasename (name)), '.');
if (cptr)
*cptr = 0;
diff --git a/gcc/gengtype-lex.l b/gcc/gengtype-lex.l
index 5788a6a26d6..fd8090606d3 100644
--- a/gcc/gengtype-lex.l
+++ b/gcc/gengtype-lex.l
@@ -50,12 +50,15 @@ update_lineno (const char *l, size_t len)
%}
-ID [[:alpha:]_][[:alnum:]_]*
+CID [[:alpha:]_][[:alnum:]_]*
WS [[:space:]]+
HWS [ \t\r\v\f]*
IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD|CPPCHAR_SIGNED_T|ino_t|dev_t|HARD_REG_SET
ITYPE {IWORD}({WS}{IWORD})*
+ /* Include '::' in identifiers to capture C++ scope qualifiers. */
+ID {CID}({HWS}::{HWS}{CID})*
EOID [^[:alnum:]_]
+CXX_KEYWORD inline|public:|private:|protected:|template|operator|friend
%x in_struct in_struct_comment in_comment
%option warn noyywrap nounput nodefault perf-report
@@ -83,6 +86,10 @@ EOID [^[:alnum:]_]
BEGIN(in_struct);
return UNION;
}
+^{HWS}class/{EOID} {
+ BEGIN(in_struct);
+ return STRUCT;
+}
^{HWS}extern/{EOID} {
BEGIN(in_struct);
return EXTERN;
@@ -93,18 +100,27 @@ EOID [^[:alnum:]_]
}
}
+ /* Parsing inside a struct, union or class declaration. */
<in_struct>{
-
"/*" { BEGIN(in_struct_comment); }
+"//".*\n { lexer_line.line++; }
{WS} { update_lineno (yytext, yyleng); }
\\\n { lexer_line.line++; }
"const"/{EOID} /* don't care */
+{CXX_KEYWORD}/{EOID} |
+"~" |
+"&" {
+ *yylval = XDUPVAR (const char, yytext, yyleng, yyleng + 1);
+ return IGNORABLE_CXX_KEYWORD;
+}
"GTY"/{EOID} { return GTY_TOKEN; }
"VEC"/{EOID} { return VEC_TOKEN; }
"union"/{EOID} { return UNION; }
"struct"/{EOID} { return STRUCT; }
+"class"/{EOID} { return STRUCT; }
+"typedef"/{EOID} { return TYPEDEF; }
"enum"/{EOID} { return ENUM; }
"ptr_alias"/{EOID} { return PTR_ALIAS; }
"nested_ptr"/{EOID} { return NESTED_PTR; }
@@ -127,7 +143,6 @@ EOID [^[:alnum:]_]
return SCALAR;
}
-
{ID}/{EOID} {
*yylval = XDUPVAR (const char, yytext, yyleng, yyleng+1);
return ID;
@@ -148,7 +163,7 @@ EOID [^[:alnum:]_]
}
"..." { return ELLIPSIS; }
-[(){},*:<>;=%|-] { return yytext[0]; }
+[(){},*:<>;=%|+-] { return yytext[0]; }
/* ignore pp-directives */
^{HWS}"#"{HWS}[a-z_]+[^\n]*\n {lexer_line.line++;}
@@ -159,6 +174,7 @@ EOID [^[:alnum:]_]
}
"/*" { BEGIN(in_comment); }
+"//".*\n { lexer_line.line++; }
\n { lexer_line.line++; }
{ID} |
"'"("\\".|[^\\])"'" |
@@ -172,6 +188,7 @@ EOID [^[:alnum:]_]
[^*\n] /* do nothing */
"*"/[^/] /* do nothing */
}
+
<in_comment>"*/" { BEGIN(INITIAL); }
<in_struct_comment>"*/" { BEGIN(in_struct); }
diff --git a/gcc/gengtype-parse.c b/gcc/gengtype-parse.c
index 03ee7819b0f..5737a156f70 100644
--- a/gcc/gengtype-parse.c
+++ b/gcc/gengtype-parse.c
@@ -87,6 +87,7 @@ static const char *const token_names[] = {
"a string constant",
"a character constant",
"an array declarator",
+ "a C++ keyword to ignore"
};
/* This array is indexed by token code minus FIRST_TOKEN_WITH_VALUE. */
@@ -98,6 +99,7 @@ static const char *const token_value_format[] = {
"'\"%s\"'",
"\"'%s'\"",
"'[%s]'",
+ "'%s'",
};
/* Produce a printable representation for a token defined by CODE and
@@ -313,78 +315,77 @@ consume_balanced (int opener, int closer)
}
/* Absorb a sequence of tokens, possibly including ()[]{}-delimited
- expressions, until we encounter a semicolon outside any such
- delimiters; absorb that too. If IMMEDIATE is true, it is an error
- if the semicolon is not the first token encountered. */
+ expressions, until we encounter an end-of-statement marker (a ';' or
+ a '}') outside any such delimiters; absorb that too. */
+
static void
-consume_until_semi (bool immediate)
+consume_until_eos (void)
{
- if (immediate && token () != ';')
- require (';');
for (;;)
switch (token ())
{
case ';':
advance ();
return;
- default:
- advance ();
- break;
+
+ case '{':
+ consume_balanced ('{', '}');
+ return;
case '(':
consume_balanced ('(', ')');
break;
+
case '[':
consume_balanced ('[', ']');
break;
- case '{':
- consume_balanced ('{', '}');
- break;
case '}':
case ']':
case ')':
parse_error ("unmatched '%c' while scanning for ';'", token ());
- return;
+ return;
case EOF_TOKEN:
parse_error ("unexpected end of file while scanning for ';'");
return;
+
+ default:
+ advance ();
+ break;
}
}
/* Absorb a sequence of tokens, possibly including ()[]{}-delimited
expressions, until we encounter a comma or semicolon outside any
- such delimiters; absorb that too. If IMMEDIATE is true, it is an
- error if the comma or semicolon is not the first token encountered.
- Returns true if the loop ended with a comma. */
+ such delimiters; absorb that too. Returns true if the loop ended
+ with a comma. */
+
static bool
-consume_until_comma_or_semi (bool immediate)
+consume_until_comma_or_eos ()
{
- if (immediate && token () != ',' && token () != ';')
- require2 (',', ';');
for (;;)
switch (token ())
{
case ',':
advance ();
return true;
+
case ';':
advance ();
return false;
- default:
- advance ();
- break;
+
+ case '{':
+ consume_balanced ('{', '}');
+ return false;
case '(':
consume_balanced ('(', ')');
break;
+
case '[':
consume_balanced ('[', ']');
break;
- case '{':
- consume_balanced ('{', '}');
- break;
case '}':
case ']':
@@ -396,6 +397,10 @@ consume_until_comma_or_semi (bool immediate)
case EOF_TOKEN:
parse_error ("unexpected end of file while scanning for ',' or ';'");
return false;
+
+ default:
+ advance ();
+ break;
}
}
@@ -548,6 +553,8 @@ gtymarker_opt (void)
return 0;
return gtymarker ();
}
+
+
/* Declarators. The logic here is largely lifted from c-parser.c.
Note that we do not have to process abstract declarators, which can
@@ -584,16 +591,21 @@ array_and_function_declarators_opt (type_p ty)
return ty;
}
-static type_p inner_declarator (type_p, const char **, options_p *);
+static type_p inner_declarator (type_p, const char **, options_p *, bool);
/* direct_declarator:
'(' inner_declarator ')'
+ '(' \epsilon ')' <-- C++ ctors/dtors
gtymarker_opt ID array_and_function_declarators_opt
Subroutine of declarator, mutually recursive with inner_declarator;
- do not use elsewhere. */
+ do not use elsewhere.
+
+ IN_STRUCT is true if we are called while parsing structures or classes. */
+
static type_p
-direct_declarator (type_p ty, const char **namep, options_p *optsp)
+direct_declarator (type_p ty, const char **namep, options_p *optsp,
+ bool in_struct)
{
/* The first token in a direct-declarator must be an ID, a
GTY marker, or an open parenthesis. */
@@ -602,18 +614,45 @@ direct_declarator (type_p ty, const char **namep, options_p *optsp)
case GTY_TOKEN:
*optsp = gtymarker ();
/* fall through */
+
case ID:
*namep = require (ID);
+ /* If the next token is '(', we are parsing a function declaration.
+ Functions are ignored by gengtype, so we return NULL. */
+ if (token () == '(')
+ return NULL;
break;
case '(':
+ /* If the declarator starts with a '(', we have three options. We
+ are either parsing 'TYPE (*ID)' (i.e., a function pointer)
+ or 'TYPE(...)'.
+
+ The latter will be a constructor iff we are inside a
+ structure or class. Otherwise, it could be a typedef, but
+ since we explicitly reject typedefs inside structures, we can
+ assume that we found a ctor and return NULL. */
advance ();
- ty = inner_declarator (ty, namep, optsp);
+ if (in_struct && token () != '*')
+ {
+ /* Found a constructor. Find and consume the closing ')'. */
+ while (token () != ')')
+ advance ();
+ advance ();
+ /* Tell the caller to ignore this. */
+ return NULL;
+ }
+ ty = inner_declarator (ty, namep, optsp, in_struct);
require (')');
break;
+ case IGNORABLE_CXX_KEYWORD:
+ /* Any C++ keyword like 'operator' means that we are not looking
+ at a regular data declarator. */
+ return NULL;
+
default:
- parse_error ("expected '(', 'GTY', or an identifier, have %s",
+ parse_error ("expected '(', ')', 'GTY', or an identifier, have %s",
print_cur_token ());
/* Do _not_ advance if what we have is a close squiggle brace, as
we will get much better error recovery that way. */
@@ -643,23 +682,26 @@ direct_declarator (type_p ty, const char **namep, options_p *optsp)
direct_declarator
Mutually recursive subroutine of direct_declarator; do not use
- elsewhere. */
+ elsewhere.
+
+ IN_STRUCT is true if we are called while parsing structures or classes. */
static type_p
-inner_declarator (type_p ty, const char **namep, options_p *optsp)
+inner_declarator (type_p ty, const char **namep, options_p *optsp,
+ bool in_struct)
{
if (token () == '*')
{
type_p inner;
advance ();
- inner = inner_declarator (ty, namep, optsp);
+ inner = inner_declarator (ty, namep, optsp, in_struct);
if (inner == 0)
return 0;
else
return create_pointer (ty);
}
else
- return direct_declarator (ty, namep, optsp);
+ return direct_declarator (ty, namep, optsp, in_struct);
}
/* declarator: '*'+ direct_declarator
@@ -667,10 +709,15 @@ inner_declarator (type_p ty, const char **namep, options_p *optsp)
This is the sole public interface to this part of the grammar.
Arguments are the type known so far, a pointer to where the name
may be stored, and a pointer to where GTY options may be stored.
- Returns the final type. */
+
+ IN_STRUCT is true when we are called to parse declarators inside
+ a structure or class.
+
+ Returns the final type. */
static type_p
-declarator (type_p ty, const char **namep, options_p *optsp)
+declarator (type_p ty, const char **namep, options_p *optsp,
+ bool in_struct = false)
{
*namep = 0;
*optsp = 0;
@@ -679,7 +726,7 @@ declarator (type_p ty, const char **namep, options_p *optsp)
advance ();
ty = create_pointer (ty);
}
- return direct_declarator (ty, namep, optsp);
+ return direct_declarator (ty, namep, optsp, in_struct);
}
/* Types and declarations. */
@@ -708,18 +755,19 @@ struct_field_seq (void)
if (!ty || token () == ':')
{
- consume_until_semi (false);
+ consume_until_eos ();
continue;
}
do
{
- dty = declarator (ty, &name, &dopts);
+ dty = declarator (ty, &name, &dopts, true);
+
/* There could be any number of weird things after the declarator,
notably bitfield declarations and __attribute__s. If this
function returns true, the last thing was a comma, so we have
more than one declarator paired with the current type. */
- another = consume_until_comma_or_semi (false);
+ another = consume_until_comma_or_eos ();
if (!dty)
continue;
@@ -760,7 +808,12 @@ opts_have (options_p opts, const char *str)
Returns a partial type; under some conditions (notably
"struct foo GTY((...)) thing;") it may write an options
structure to *OPTSP.
-*/
+
+ NESTED is true when parsing a declaration already known to have a
+ GTY marker. In these cases, typedef and enum declarations are not
+ allowed because gengtype only understands types at the global
+ scope. */
+
static type_p
type (options_p *optsp, bool nested)
{
@@ -777,6 +830,12 @@ type (options_p *optsp, bool nested)
s = typedef_name ();
return resolve_typedef (s, &lexer_line);
+ case IGNORABLE_CXX_KEYWORD:
+ /* By returning NULL here, we indicate to the caller that they
+ should ignore everything following this keyword up to the
+ next ';' or '}'. */
+ return NULL;
+
case STRUCT:
case UNION:
{
@@ -796,8 +855,8 @@ type (options_p *optsp, bool nested)
/* Top-level structures that are not explicitly tagged GTY(())
are treated as mere forward declarations. This is because
there are a lot of structures that we don't need to know
- about, and some of those have weird macro stuff in them
- that we can't handle. */
+ about, and some of those have C++ and macro constructs that
+ we cannot handle. */
if (nested || token () == GTY_TOKEN)
{
is_gty = GTY_BEFORE_ID;
@@ -819,6 +878,13 @@ type (options_p *optsp, bool nested)
opts = gtymarker_opt ();
}
+ if (token () == ':')
+ {
+ /* Skip over C++ inheritance specification. */
+ while (token () != '{')
+ advance ();
+ }
+
if (is_gty)
{
bool is_user_gty = opts_have (opts, "user");
@@ -853,6 +919,21 @@ type (options_p *optsp, bool nested)
return find_structure (s, kind);
}
+ case TYPEDEF:
+ /* In C++, a typedef inside a struct/class/union defines a new
+ type for that inner scope. We cannot support this in
+ gengtype because we have no concept of scoping.
+
+ We handle typedefs in the global scope separately (see
+ parse_file), so if we find a 'typedef', we must be inside
+ a struct. */
+ gcc_assert (nested);
+ parse_error ("typedefs not supported in structures marked with "
+ "automatic GTY markers. Use GTY((user)) to mark "
+ "this structure.");
+ advance ();
+ return NULL;
+
case ENUM:
advance ();
if (token () == ID)
@@ -864,6 +945,23 @@ type (options_p *optsp, bool nested)
if (token () == '{')
consume_balanced ('{', '}');
+
+ /* If after parsing the enum we are at the end of the statement,
+ and we are currently inside a structure, then this was an
+ enum declaration inside this scope.
+
+ We cannot support this for the same reason we cannot support
+ 'typedef' inside structures (see the TYPEDEF handler above).
+ If this happens, emit an error and return NULL. */
+ if (nested && token () == ';')
+ {
+ parse_error ("enum definitions not supported in structures marked "
+ "with automatic GTY markers. Use GTY((user)) to mark "
+ "this structure.");
+ advance ();
+ return NULL;
+ }
+
return create_scalar_type (s);
default:
@@ -901,7 +999,7 @@ typedef_decl (void)
/* Yet another place where we could have junk (notably attributes)
after the declarator. */
- another = consume_until_comma_or_semi (false);
+ another = consume_until_comma_or_eos ();
if (dty)
do_typedef (name, dty, &lexer_line);
}
diff --git a/gcc/gengtype-state.c b/gcc/gengtype-state.c
index c94d50b1ef6..e3317ec36a4 100644
--- a/gcc/gengtype-state.c
+++ b/gcc/gengtype-state.c
@@ -961,6 +961,8 @@ write_state_type (type_p current)
current->state_number = state_written_type_count;
switch (current->kind)
{
+ case TYPE_NONE:
+ gcc_unreachable ();
case TYPE_STRUCT:
write_state_struct_type (current);
break;
@@ -988,9 +990,6 @@ write_state_type (type_p current)
case TYPE_STRING:
write_state_string_type (current);
break;
-
- default:
- fatal ("Unexpected type...");
}
}
@@ -1318,7 +1317,6 @@ read_state_scalar_char_type (type_p *type)
read_state_common_type_content (*type);
}
-
/* Read the string_type. */
static void
read_state_string_type (type_p *type)
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 4a36d567df1..70cc1e83bf4 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -497,10 +497,10 @@ struct type scalar_char = {
/* Lists of various things. */
-pair_p typedefs;
-type_p structures;
-type_p param_structs;
-pair_p variables;
+pair_p typedefs = NULL;
+type_p structures = NULL;
+type_p param_structs = NULL;
+pair_p variables = NULL;
static type_p find_param_structure (type_p t, type_p param[NUM_PARAM]);
static type_p adjust_field_tree_exp (type_p t, options_p opt);
@@ -611,6 +611,7 @@ resolve_typedef (const char *s, struct fileloc *pos)
return create_user_defined_type (s, pos);
}
+
/* Create and return a new structure with tag NAME at POS with fields
FIELDS and options O. The KIND of structure must be one of
TYPE_STRUCT, TYPE_UNION or TYPE_USER_STRUCT. */
@@ -676,8 +677,7 @@ new_structure (const char *name, enum typekind kind, struct fileloc *pos,
structures = s;
}
- if (s->u.s.line.file != NULL
- || (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap)))
+ if (s->u.s.lang_struct && (s->u.s.lang_struct->u.s.bitmap & bitmap))
{
error_at_line (pos, "duplicate definition of '%s %s'",
isunion ? "union" : "struct", s->u.s.tag);
@@ -763,6 +763,7 @@ create_scalar_type (const char *name)
return &scalar_nonchar;
}
+
/* Return a pointer to T. */
type_p
@@ -2641,7 +2642,7 @@ walk_type (type_p t, struct walk_type_data *d)
/* If a pointer type is marked as "atomic", we process the
field itself, but we don't walk the data that they point to.
-
+
There are two main cases where we walk types: to mark
pointers that are reachable, and to relocate pointers when
writing a PCH file. In both cases, an atomic pointer is
@@ -3519,7 +3520,7 @@ write_func_for_structure (type_p orig_s, type_p s, type_p *param,
{
oprintf (d.of, " %s (x);\n", mark_hook_name);
}
-
+
d.prev_val[2] = "*x";
d.indent = 6;
if (orig_s->kind != TYPE_USER_STRUCT)
diff --git a/gcc/gengtype.h b/gcc/gengtype.h
index 4a178ec3967..e687e488567 100644
--- a/gcc/gengtype.h
+++ b/gcc/gengtype.h
@@ -308,7 +308,6 @@ struct type {
type_p param[NUM_PARAM]; /* The actual parameter types. */
struct fileloc line; /* The source location. */
} param_struct;
-
} u;
};
@@ -444,38 +443,38 @@ extern void parse_file (const char *name);
extern bool hit_error;
/* Token codes. */
-enum
- {
- EOF_TOKEN = 0,
-
- /* Per standard convention, codes in the range (0, UCHAR_MAX]
- represent single characters with those character codes. */
-
- CHAR_TOKEN_OFFSET = UCHAR_MAX + 1,
- GTY_TOKEN = CHAR_TOKEN_OFFSET,
- TYPEDEF,
- EXTERN,
- STATIC,
- UNION,
- STRUCT,
- ENUM,
- VEC_TOKEN,
- ELLIPSIS,
- PTR_ALIAS,
- NESTED_PTR,
- USER_GTY,
- PARAM_IS,
- NUM,
- SCALAR,
- ID,
- STRING,
- CHAR,
- ARRAY,
-
- /* print_token assumes that any token >= FIRST_TOKEN_WITH_VALUE may have
- a meaningful value to be printed. */
- FIRST_TOKEN_WITH_VALUE = PARAM_IS
- };
+enum gty_token
+{
+ EOF_TOKEN = 0,
+
+ /* Per standard convention, codes in the range (0, UCHAR_MAX]
+ represent single characters with those character codes. */
+ CHAR_TOKEN_OFFSET = UCHAR_MAX + 1,
+ GTY_TOKEN = CHAR_TOKEN_OFFSET,
+ TYPEDEF,
+ EXTERN,
+ STATIC,
+ UNION,
+ STRUCT,
+ ENUM,
+ VEC_TOKEN,
+ ELLIPSIS,
+ PTR_ALIAS,
+ NESTED_PTR,
+ USER_GTY,
+ PARAM_IS,
+ NUM,
+ SCALAR,
+ ID,
+ STRING,
+ CHAR,
+ ARRAY,
+ IGNORABLE_CXX_KEYWORD,
+
+ /* print_token assumes that any token >= FIRST_TOKEN_WITH_VALUE may have
+ a meaningful value to be printed. */
+ FIRST_TOKEN_WITH_VALUE = PARAM_IS
+};
/* Level for verbose messages, e.g. output file generation... */
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index 2c6104cb25a..d736d2c027f 100644
--- a/gcc/genoutput.c
+++ b/gcc/genoutput.c
@@ -1,6 +1,6 @@
/* Generate code from to output assembler insns as recognized from rtl.
Copyright (C) 1987, 1988, 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2002,
- 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2012
+ 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
This file is part of GCC.
@@ -662,19 +662,55 @@ process_template (struct data *d, const char *template_code)
list of assembler code templates, one for each alternative. */
else if (template_code[0] == '@')
{
- d->template_code = 0;
- d->output_format = INSN_OUTPUT_FORMAT_MULTI;
+ int found_star = 0;
- printf ("\nstatic const char * const output_%d[] = {\n", d->code_number);
+ for (cp = &template_code[1]; *cp; )
+ {
+ while (ISSPACE (*cp))
+ cp++;
+ if (*cp == '*')
+ found_star = 1;
+ while (!IS_VSPACE (*cp) && *cp != '\0')
+ ++cp;
+ }
+ d->template_code = 0;
+ if (found_star)
+ {
+ d->output_format = INSN_OUTPUT_FORMAT_FUNCTION;
+ puts ("\nstatic const char *");
+ printf ("output_%d (rtx *operands ATTRIBUTE_UNUSED, "
+ "rtx insn ATTRIBUTE_UNUSED)\n", d->code_number);
+ puts ("{");
+ puts (" switch (which_alternative)\n {");
+ }
+ else
+ {
+ d->output_format = INSN_OUTPUT_FORMAT_MULTI;
+ printf ("\nstatic const char * const output_%d[] = {\n",
+ d->code_number);
+ }
for (i = 0, cp = &template_code[1]; *cp; )
{
- const char *ep, *sp;
+ const char *ep, *sp, *bp;
while (ISSPACE (*cp))
cp++;
- printf (" \"");
+ bp = cp;
+ if (found_star)
+ {
+ printf (" case %d:", i);
+ if (*cp == '*')
+ {
+ printf ("\n ");
+ cp++;
+ }
+ else
+ printf (" return \"");
+ }
+ else
+ printf (" \"");
for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
if (!ISSPACE (*ep))
@@ -690,7 +726,18 @@ process_template (struct data *d, const char *template_code)
cp++;
}
- printf ("\",\n");
+ if (!found_star)
+ puts ("\",");
+ else if (*bp != '*')
+ puts ("\";");
+ else
+ {
+ /* The usual action will end with a return.
+ If there is neither break or return at the end, this is
+ assumed to be intentional; this allows to have multiple
+ consecutive alternatives share some code. */
+ puts ("");
+ }
i++;
}
if (i == 1)
@@ -700,7 +747,10 @@ process_template (struct data *d, const char *template_code)
error_with_line (d->lineno,
"wrong number of alternatives in the output template");
- printf ("};\n");
+ if (found_star)
+ puts (" default: gcc_unreachable ();\n }\n}");
+ else
+ printf ("};\n");
}
else
{
diff --git a/gcc/gimple-streamer-in.c b/gcc/gimple-streamer-in.c
index e2934c7fa8d..0ad0fb1acfa 100644
--- a/gcc/gimple-streamer-in.c
+++ b/gcc/gimple-streamer-in.c
@@ -53,7 +53,8 @@ input_phi (struct lto_input_block *ib, basic_block bb, struct data_in *data_in,
{
tree def = stream_read_tree (ib, data_in);
int src_index = streamer_read_uhwi (ib);
- location_t arg_loc = lto_input_location (ib, data_in);
+ bitpack_d bp = streamer_read_bitpack (ib);
+ location_t arg_loc = stream_input_location (&bp, data_in);
basic_block sbb = BASIC_BLOCK_FOR_FUNCTION (fn, src_index);
edge e = NULL;
@@ -99,7 +100,7 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
stmt->gsbase.subcode = bp_unpack_var_len_unsigned (&bp);
/* Read location information. */
- gimple_set_location (stmt, lto_input_location (ib, data_in));
+ gimple_set_location (stmt, stream_input_location (&bp, data_in));
/* Read lexical block reference. */
gimple_set_block (stmt, stream_read_tree (ib, data_in));
diff --git a/gcc/gimple-streamer-out.c b/gcc/gimple-streamer-out.c
index 22bcbca8d17..e49400b34de 100644
--- a/gcc/gimple-streamer-out.c
+++ b/gcc/gimple-streamer-out.c
@@ -43,7 +43,9 @@ output_phi (struct output_block *ob, gimple phi)
{
stream_write_tree (ob, gimple_phi_arg_def (phi, i), true);
streamer_write_uhwi (ob, gimple_phi_arg_edge (phi, i)->src->index);
- lto_output_location (ob, gimple_phi_arg_location (phi, i));
+ bitpack_d bp = bitpack_create (ob->main_stream);
+ stream_output_location (ob, &bp, gimple_phi_arg_location (phi, i));
+ streamer_write_bitpack (&bp);
}
}
@@ -71,10 +73,10 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
bp_pack_value (&bp, gimple_assign_nontemporal_move_p (stmt), 1);
bp_pack_value (&bp, gimple_has_volatile_ops (stmt), 1);
bp_pack_var_len_unsigned (&bp, stmt->gsbase.subcode);
- streamer_write_bitpack (&bp);
/* Emit location information for the statement. */
- lto_output_location (ob, LOCATION_LOCUS (gimple_location (stmt)));
+ stream_output_location (ob, &bp, LOCATION_LOCUS (gimple_location (stmt)));
+ streamer_write_bitpack (&bp);
/* Emit the lexical block holding STMT. */
stream_write_tree (ob, gimple_block (stmt), true);
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 979715ab95e..b83a6346eca 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -7683,6 +7683,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
}
case FMA_EXPR:
+ case VEC_COND_EXPR:
case VEC_PERM_EXPR:
/* Classified as tcc_expression. */
goto expr_3;
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index fb2346bdc45..714dd8f7bcb 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -287,6 +287,18 @@ ipa_print_all_jump_functions (FILE *f)
}
}
+/* Worker for prune_expression_for_jf. */
+
+static tree
+prune_expression_for_jf_1 (tree *tp, int *walk_subtrees, void *)
+{
+ if (EXPR_P (*tp))
+ SET_EXPR_LOCATION (*tp, UNKNOWN_LOCATION);
+ else
+ *walk_subtrees = 0;
+ return NULL_TREE;
+}
+
/* Return the expression tree EXPR unshared and with location stripped off. */
static tree
@@ -295,7 +307,7 @@ prune_expression_for_jf (tree exp)
if (EXPR_P (exp))
{
exp = unshare_expr (exp);
- SET_EXPR_LOCATION (exp, UNKNOWN_LOCATION);
+ walk_tree (&exp, prune_expression_for_jf_1, NULL, NULL);
}
return exp;
}
diff --git a/gcc/ira-build.c b/gcc/ira-build.c
index 1181813d92b..986bb5e5f62 100644
--- a/gcc/ira-build.c
+++ b/gcc/ira-build.c
@@ -1458,6 +1458,96 @@ finish_cost_vectors (void)
+/* Compute a post-ordering of the reverse control flow of the loop body
+ designated by the children nodes of LOOP_NODE, whose body nodes in
+ pre-order are input as LOOP_PREORDER. Return a VEC with a post-order
+ of the reverse loop body.
+
+ For the post-order of the reverse CFG, we visit the basic blocks in
+ LOOP_PREORDER array in the reverse order of where they appear.
+ This is important: We do not just want to compute a post-order of
+ the reverse CFG, we want to make a best-guess for a visiting order that
+ minimizes the number of chain elements per allocno live range. If the
+ blocks would be visited in a different order, we would still compute a
+ correct post-ordering but it would be less likely that two nodes
+ connected by an edge in the CFG are neighbours in the topsort. */
+
+static VEC (ira_loop_tree_node_t, heap) *
+ira_loop_tree_body_rev_postorder (ira_loop_tree_node_t loop_node ATTRIBUTE_UNUSED,
+ VEC (ira_loop_tree_node_t, heap) *loop_preorder)
+{
+ VEC (ira_loop_tree_node_t, heap) *topsort_nodes = NULL;
+ unsigned int n_loop_preorder;
+
+ n_loop_preorder = VEC_length (ira_loop_tree_node_t, loop_preorder);
+ if (n_loop_preorder != 0)
+ {
+ ira_loop_tree_node_t subloop_node;
+ unsigned int i;
+ VEC (ira_loop_tree_node_t, heap) *dfs_stack;
+
+ /* This is a bit of strange abuse of the BB_VISITED flag: We use
+ the flag to mark blocks we still have to visit to add them to
+ our post-order. Define an alias to avoid confusion. */
+#define BB_TO_VISIT BB_VISITED
+
+ FOR_EACH_VEC_ELT (ira_loop_tree_node_t, loop_preorder, i, subloop_node)
+ {
+ gcc_checking_assert (! (subloop_node->bb->flags & BB_TO_VISIT));
+ subloop_node->bb->flags |= BB_TO_VISIT;
+ }
+
+ topsort_nodes = VEC_alloc (ira_loop_tree_node_t, heap, n_loop_preorder);
+ dfs_stack = VEC_alloc (ira_loop_tree_node_t, heap, n_loop_preorder);
+
+ FOR_EACH_VEC_ELT_REVERSE (ira_loop_tree_node_t, loop_preorder,
+ i, subloop_node)
+ {
+ if (! (subloop_node->bb->flags & BB_TO_VISIT))
+ continue;
+
+ subloop_node->bb->flags &= ~BB_TO_VISIT;
+ VEC_quick_push (ira_loop_tree_node_t, dfs_stack, subloop_node);
+ while (! VEC_empty (ira_loop_tree_node_t, dfs_stack))
+ {
+ edge e;
+ edge_iterator ei;
+
+ ira_loop_tree_node_t n = VEC_last (ira_loop_tree_node_t,
+ dfs_stack);
+ FOR_EACH_EDGE (e, ei, n->bb->preds)
+ {
+ ira_loop_tree_node_t pred_node;
+ basic_block pred_bb = e->src;
+
+ if (e->src == ENTRY_BLOCK_PTR)
+ continue;
+
+ pred_node = IRA_BB_NODE_BY_INDEX (pred_bb->index);
+ if (pred_node != n
+ && (pred_node->bb->flags & BB_TO_VISIT))
+ {
+ pred_node->bb->flags &= ~BB_TO_VISIT;
+ VEC_quick_push (ira_loop_tree_node_t, dfs_stack, pred_node);
+ }
+ }
+ if (n == VEC_last (ira_loop_tree_node_t, dfs_stack))
+ {
+ VEC_pop (ira_loop_tree_node_t, dfs_stack);
+ VEC_quick_push (ira_loop_tree_node_t, topsort_nodes, n);
+ }
+ }
+ }
+
+#undef BB_TO_VISIT
+ VEC_free (ira_loop_tree_node_t, heap, dfs_stack);
+ }
+
+ gcc_assert (VEC_length (ira_loop_tree_node_t, topsort_nodes)
+ == n_loop_preorder);
+ return topsort_nodes;
+}
+
/* The current loop tree node and its regno allocno map. */
ira_loop_tree_node_t ira_curr_loop_tree_node;
ira_allocno_t *ira_curr_regno_allocno_map;
@@ -1467,7 +1557,16 @@ ira_allocno_t *ira_curr_regno_allocno_map;
correspondingly in preorder and postorder. The function sets up
IRA_CURR_LOOP_TREE_NODE and IRA_CURR_REGNO_ALLOCNO_MAP. If BB_P,
basic block nodes of LOOP_NODE is also processed (before its
- subloop nodes). */
+ subloop nodes).
+
+ If BB_P is set and POSTORDER_FUNC is given, the basic blocks in
+ the loop are passed in the *reverse* post-order of the *reverse*
+ CFG. This is only used by ira_create_allocno_live_ranges, which
+ wants to visit basic blocks in this order to minimize the number
+ of elements per live range chain.
+ Note that the loop tree nodes are still visited in the normal,
+ forward post-order of the loop tree. */
+
void
ira_traverse_loop_tree (bool bb_p, ira_loop_tree_node_t loop_node,
void (*preorder_func) (ira_loop_tree_node_t),
@@ -1483,18 +1582,37 @@ ira_traverse_loop_tree (bool bb_p, ira_loop_tree_node_t loop_node,
(*preorder_func) (loop_node);
if (bb_p)
- for (subloop_node = loop_node->children;
- subloop_node != NULL;
- subloop_node = subloop_node->next)
- if (subloop_node->bb != NULL)
- {
- if (preorder_func != NULL)
- (*preorder_func) (subloop_node);
+ {
+ VEC (ira_loop_tree_node_t, heap) *loop_preorder = NULL;
+ unsigned int i;
+
+ /* Add all nodes to the set of nodes to visit. The IRA loop tree
+ is set up such that nodes in the loop body appear in a pre-order
+ of their place in the CFG. */
+ for (subloop_node = loop_node->children;
+ subloop_node != NULL;
+ subloop_node = subloop_node->next)
+ if (subloop_node->bb != NULL)
+ VEC_safe_push (ira_loop_tree_node_t, heap,
+ loop_preorder, subloop_node);
+
+ if (preorder_func != NULL)
+ FOR_EACH_VEC_ELT (ira_loop_tree_node_t, loop_preorder, i, subloop_node)
+ (*preorder_func) (subloop_node);
- if (postorder_func != NULL)
+ if (postorder_func != NULL)
+ {
+ VEC (ira_loop_tree_node_t, heap) *loop_rev_postorder =
+ ira_loop_tree_body_rev_postorder (loop_node, loop_preorder);
+ FOR_EACH_VEC_ELT_REVERSE (ira_loop_tree_node_t, loop_rev_postorder,
+ i, subloop_node)
(*postorder_func) (subloop_node);
+ VEC_free (ira_loop_tree_node_t, heap, loop_rev_postorder);
}
+ VEC_free (ira_loop_tree_node_t, heap, loop_preorder);
+ }
+
for (subloop_node = loop_node->subloops;
subloop_node != NULL;
subloop_node = subloop_node->subloop_next)
@@ -1597,7 +1715,7 @@ create_bb_allocnos (ira_loop_tree_node_t bb_node)
create_insn_allocnos (PATTERN (insn), false);
/* It might be a allocno living through from one subloop to
another. */
- EXECUTE_IF_SET_IN_REG_SET (DF_LR_IN (bb), FIRST_PSEUDO_REGISTER, i, bi)
+ EXECUTE_IF_SET_IN_REG_SET (df_get_live_in (bb), FIRST_PSEUDO_REGISTER, i, bi)
if (ira_curr_regno_allocno_map[i] == NULL)
ira_create_allocno (i, false, ira_curr_loop_tree_node);
}
@@ -1613,9 +1731,9 @@ create_loop_allocnos (edge e)
bitmap_iterator bi;
ira_loop_tree_node_t parent;
- live_in_regs = DF_LR_IN (e->dest);
+ live_in_regs = df_get_live_in (e->dest);
border_allocnos = ira_curr_loop_tree_node->border_allocnos;
- EXECUTE_IF_SET_IN_REG_SET (DF_LR_OUT (e->src),
+ EXECUTE_IF_SET_IN_REG_SET (df_get_live_out (e->src),
FIRST_PSEUDO_REGISTER, i, bi)
if (bitmap_bit_p (live_in_regs, i))
{
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index fc2e4e8b29b..bcf03216af8 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -2014,8 +2014,8 @@ ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
FOR_EACH_EDGE (e, ei, loop_node->loop->header->preds)
if (e->src != loop_node->loop->latch
&& (regno < 0
- || (bitmap_bit_p (DF_LR_OUT (e->src), regno)
- && bitmap_bit_p (DF_LR_IN (e->dest), regno))))
+ || (bitmap_bit_p (df_get_live_out (e->src), regno)
+ && bitmap_bit_p (df_get_live_in (e->dest), regno))))
freq += EDGE_FREQUENCY (e);
}
else
@@ -2023,8 +2023,8 @@ ira_loop_edge_freq (ira_loop_tree_node_t loop_node, int regno, bool exit_p)
edges = get_loop_exit_edges (loop_node->loop);
FOR_EACH_VEC_ELT (edge, edges, i, e)
if (regno < 0
- || (bitmap_bit_p (DF_LR_OUT (e->src), regno)
- && bitmap_bit_p (DF_LR_IN (e->dest), regno)))
+ || (bitmap_bit_p (df_get_live_out (e->src), regno)
+ && bitmap_bit_p (df_get_live_in (e->dest), regno)))
freq += EDGE_FREQUENCY (e);
VEC_free (edge, heap, edges);
}
diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c
index 583629bf5a0..d124ef28cab 100644
--- a/gcc/ira-conflicts.c
+++ b/gcc/ira-conflicts.c
@@ -860,7 +860,7 @@ ira_build_conflicts (void)
ira_object_iterator oi;
build_conflicts ();
- ira_traverse_loop_tree (true, ira_loop_tree_root, NULL, add_copies);
+ ira_traverse_loop_tree (true, ira_loop_tree_root, add_copies, NULL);
/* We need finished conflict table for the subsequent call. */
if (flag_ira_region == IRA_REGION_ALL
|| flag_ira_region == IRA_REGION_MIXED)
diff --git a/gcc/ira-emit.c b/gcc/ira-emit.c
index dbab5374173..b0d9a825124 100644
--- a/gcc/ira-emit.c
+++ b/gcc/ira-emit.c
@@ -495,6 +495,7 @@ generate_edge_moves (edge e)
bitmap_iterator bi;
ira_allocno_t src_allocno, dest_allocno, *src_map, *dest_map;
move_t move;
+ bitmap regs_live_in_dest, regs_live_out_src;
src_loop_node = IRA_BB_NODE (e->src)->parent;
dest_loop_node = IRA_BB_NODE (e->dest)->parent;
@@ -503,9 +504,11 @@ generate_edge_moves (edge e)
return;
src_map = src_loop_node->regno_allocno_map;
dest_map = dest_loop_node->regno_allocno_map;
- EXECUTE_IF_SET_IN_REG_SET (DF_LR_IN (e->dest),
+ regs_live_in_dest = df_get_live_in (e->dest);
+ regs_live_out_src = df_get_live_out (e->src);
+ EXECUTE_IF_SET_IN_REG_SET (regs_live_in_dest,
FIRST_PSEUDO_REGISTER, regno, bi)
- if (bitmap_bit_p (DF_LR_OUT (e->src), regno))
+ if (bitmap_bit_p (regs_live_out_src, regno))
{
src_allocno = src_map[regno];
dest_allocno = dest_map[regno];
@@ -1206,15 +1209,16 @@ add_ranges_and_copies (void)
destination block) to use for searching allocnos by their
regnos because of subsequent IR flattening. */
node = IRA_BB_NODE (bb)->parent;
- bitmap_copy (live_through, DF_LR_IN (bb));
+ bitmap_copy (live_through, df_get_live_in (bb));
add_range_and_copies_from_move_list
(at_bb_start[bb->index], node, live_through, REG_FREQ_FROM_BB (bb));
- bitmap_copy (live_through, DF_LR_OUT (bb));
+ bitmap_copy (live_through, df_get_live_out (bb));
add_range_and_copies_from_move_list
(at_bb_end[bb->index], node, live_through, REG_FREQ_FROM_BB (bb));
FOR_EACH_EDGE (e, ei, bb->succs)
{
- bitmap_and (live_through, DF_LR_IN (e->dest), DF_LR_OUT (bb));
+ bitmap_and (live_through,
+ df_get_live_in (e->dest), df_get_live_out (bb));
add_range_and_copies_from_move_list
((move_t) e->aux, node, live_through,
REG_FREQ_FROM_EDGE_FREQ (EDGE_FREQUENCY (e)));
diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c
index 853832e3c9f..940cd681f2a 100644
--- a/gcc/ira-lives.c
+++ b/gcc/ira-lives.c
@@ -1148,7 +1148,7 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
high_pressure_start_point[ira_pressure_classes[i]] = -1;
}
curr_bb_node = loop_tree_node;
- reg_live_out = DF_LR_OUT (bb);
+ reg_live_out = df_get_live_out (bb);
sparseset_clear (objects_live);
REG_SET_TO_HARD_REG_SET (hard_regs_live, reg_live_out);
AND_COMPL_HARD_REG_SET (hard_regs_live, eliminable_regset);
@@ -1458,7 +1458,7 @@ remove_some_program_points_and_update_live_ranges (void)
int *map;
ira_object_t obj;
ira_object_iterator oi;
- live_range_t r;
+ live_range_t r, prev_r, next_r;
sbitmap born_or_dead, born, dead;
sbitmap_iterator sbi;
bool born_p, dead_p, prev_born_p, prev_dead_p;
@@ -1502,10 +1502,19 @@ remove_some_program_points_and_update_live_ranges (void)
ira_max_point = n;
FOR_EACH_OBJECT (obj, oi)
- for (r = OBJECT_LIVE_RANGES (obj); r != NULL; r = r->next)
+ for (r = OBJECT_LIVE_RANGES (obj), prev_r = NULL; r != NULL; r = next_r)
{
+ next_r = r->next;
r->start = map[r->start];
r->finish = map[r->finish];
+ if (prev_r == NULL || prev_r->start > r->finish + 1)
+ {
+ prev_r = r;
+ continue;
+ }
+ prev_r->start = r->start;
+ prev_r->next = next_r;
+ ira_finish_live_range (r);
}
ira_free (map);
diff --git a/gcc/ira.c b/gcc/ira.c
index 4a7dcb52043..a79a0dcdff3 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -2337,16 +2337,23 @@ void
mark_elimination (int from, int to)
{
basic_block bb;
+ bitmap r;
FOR_EACH_BB (bb)
{
- /* We don't use LIVE info in IRA. */
- bitmap r = DF_LR_IN (bb);
-
- if (REGNO_REG_SET_P (r, from))
+ r = DF_LR_IN (bb);
+ if (bitmap_bit_p (r, from))
+ {
+ bitmap_clear_bit (r, from);
+ bitmap_set_bit (r, to);
+ }
+ if (! df_live)
+ continue;
+ r = DF_LIVE_IN (bb);
+ if (bitmap_bit_p (r, from))
{
- CLEAR_REGNO_REG_SET (r, from);
- SET_REGNO_REG_SET (r, to);
+ bitmap_clear_bit (r, from);
+ bitmap_set_bit (r, to);
}
}
}
@@ -3194,10 +3201,12 @@ update_equiv_regs (void)
{
FOR_EACH_BB (bb)
{
- bitmap_and_compl_into (DF_LIVE_IN (bb), cleared_regs);
- bitmap_and_compl_into (DF_LIVE_OUT (bb), cleared_regs);
bitmap_and_compl_into (DF_LR_IN (bb), cleared_regs);
bitmap_and_compl_into (DF_LR_OUT (bb), cleared_regs);
+ if (! df_live)
+ continue;
+ bitmap_and_compl_into (DF_LIVE_IN (bb), cleared_regs);
+ bitmap_and_compl_into (DF_LIVE_OUT (bb), cleared_regs);
}
/* Last pass - adjust debug insns referencing cleared regs. */
@@ -3319,14 +3328,14 @@ build_insn_chain (void)
CLEAR_REG_SET (live_relevant_regs);
bitmap_clear (live_subregs_used);
- EXECUTE_IF_SET_IN_BITMAP (DF_LR_OUT (bb), 0, i, bi)
+ EXECUTE_IF_SET_IN_BITMAP (df_get_live_out (bb), 0, i, bi)
{
if (i >= FIRST_PSEUDO_REGISTER)
break;
bitmap_set_bit (live_relevant_regs, i);
}
- EXECUTE_IF_SET_IN_BITMAP (DF_LR_OUT (bb),
+ EXECUTE_IF_SET_IN_BITMAP (df_get_live_out (bb),
FIRST_PSEUDO_REGISTER, i, bi)
{
if (pseudo_for_reload_consideration_p (i))
@@ -4157,12 +4166,6 @@ ira (FILE *f)
setup_prohibited_mode_move_regs ();
df_note_add_problem ();
-
- if (optimize == 1)
- {
- df_live_add_problem ();
- df_live_set_all_dirty ();
- }
#ifdef ENABLE_CHECKING
df->changeable_flags |= DF_VERIFY_SCHEDULED;
#endif
@@ -4233,8 +4236,8 @@ ira (FILE *f)
if (flag_ira_region == IRA_REGION_ALL || flag_ira_region == IRA_REGION_MIXED)
{
flow_loops_find (&ira_loops);
- record_loop_exits ();
current_loops = &ira_loops;
+ record_loop_exits ();
}
if (internal_flag_ira_verbose > 0 && ira_dump_file != NULL)
@@ -4277,9 +4280,14 @@ ira (FILE *f)
info. */
df_analyze ();
+ /* ??? Rebuild the loop tree, but why? Does the loop tree
+ change if new insns were generated? Can that be handled
+ by updating the loop tree incrementally? */
+ release_recorded_exits ();
+ flow_loops_free (&ira_loops);
flow_loops_find (&ira_loops);
- record_loop_exits ();
current_loops = &ira_loops;
+ record_loop_exits ();
setup_allocno_assignment_flags ();
ira_initiate_assign ();
@@ -4363,6 +4371,7 @@ do_reload (void)
if (current_loops != NULL)
{
+ release_recorded_exits ();
flow_loops_free (&ira_loops);
free_dominance_info (CDI_DOMINATORS);
}
@@ -4391,8 +4400,6 @@ do_reload (void)
df_rescan_all_insns is not going to help here because it does not
touch the artificial uses and defs. */
df_finish_pass (true);
- if (optimize > 1)
- df_live_add_problem ();
df_scan_alloc (NULL);
df_scan_blocks ();
diff --git a/gcc/loop-iv.c b/gcc/loop-iv.c
index 658f20360f7..4619c626b7b 100644
--- a/gcc/loop-iv.c
+++ b/gcc/loop-iv.c
@@ -2004,11 +2004,30 @@ simplify_using_initial_values (struct loop *loop, enum rtx_code op, rtx *expr)
}
}
else
- /* If we did not use this insn to make a replacement, any overlap
- between stores in this insn and our expression will cause the
- expression to become invalid. */
- if (for_each_rtx (expr, altered_reg_used, this_altered))
- goto out;
+ {
+ rtx *pnote, *pnote_next;
+
+ /* If we did not use this insn to make a replacement, any overlap
+ between stores in this insn and our expression will cause the
+ expression to become invalid. */
+ if (for_each_rtx (expr, altered_reg_used, this_altered))
+ goto out;
+
+ /* Likewise for the conditions. */
+ for (pnote = &cond_list; *pnote; pnote = pnote_next)
+ {
+ rtx note = *pnote;
+ rtx old_cond = XEXP (note, 0);
+
+ pnote_next = &XEXP (note, 1);
+ if (for_each_rtx (&old_cond, altered_reg_used, this_altered))
+ {
+ *pnote = *pnote_next;
+ pnote_next = pnote;
+ free_EXPR_LIST_node (note);
+ }
+ }
+ }
if (CONSTANT_P (*expr))
goto out;
@@ -2224,13 +2243,18 @@ determine_max_iter (struct loop *loop, struct niter_desc *desc, rtx old_niter)
rtx niter = desc->niter_expr;
rtx mmin, mmax, cmp;
unsigned HOST_WIDEST_INT nmax, inc;
+ unsigned HOST_WIDEST_INT andmax = 0;
+
+ /* We used to look for constant operand 0 of AND,
+ but canonicalization should always make this impossible. */
+ gcc_checking_assert (GET_CODE (niter) != AND
+ || !CONST_INT_P (XEXP (niter, 0)));
if (GET_CODE (niter) == AND
- && CONST_INT_P (XEXP (niter, 0)))
+ && CONST_INT_P (XEXP (niter, 1)))
{
- nmax = INTVAL (XEXP (niter, 0));
- if (!(nmax & (nmax + 1)))
- return nmax;
+ andmax = UINTVAL (XEXP (niter, 1));
+ niter = XEXP (niter, 0);
}
get_mode_bounds (desc->mode, desc->signed_p, desc->mode, &mmin, &mmax);
@@ -2258,7 +2282,13 @@ determine_max_iter (struct loop *loop, struct niter_desc *desc, rtx old_niter)
if (dump_file)
fprintf (dump_file, ";; improved upper bound by one.\n");
}
- return nmax / inc;
+ nmax /= inc;
+ if (andmax)
+ nmax = MIN (nmax, andmax);
+ if (dump_file)
+ fprintf (dump_file, ";; Determined upper bound "HOST_WIDEST_INT_PRINT_DEC".\n",
+ nmax);
+ return nmax;
}
/* Computes number of iterations of the CONDITION in INSN in LOOP and stores
@@ -2563,7 +2593,7 @@ iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition,
? iv0.base
: mode_mmin);
max = (up - down) / inc + 1;
- record_niter_bound (loop, double_int::from_shwi (max),
+ record_niter_bound (loop, double_int::from_uhwi (max),
false, true);
if (iv0.step == const0_rtx)
@@ -2776,14 +2806,14 @@ iv_number_of_iterations (struct loop *loop, rtx insn, rtx condition,
desc->const_iter = true;
desc->niter = val & GET_MODE_MASK (desc->mode);
- record_niter_bound (loop, double_int::from_shwi (desc->niter),
+ record_niter_bound (loop, double_int::from_uhwi (desc->niter),
false, true);
}
else
{
max = determine_max_iter (loop, desc, old_niter);
gcc_assert (max);
- record_niter_bound (loop, double_int::from_shwi (max),
+ record_niter_bound (loop, double_int::from_uhwi (max),
false, true);
/* simplify_using_initial_values does a copy propagation on the registers
diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
index b6dace030c1..0dd8b0a9d5c 100644
--- a/gcc/loop-unroll.c
+++ b/gcc/loop-unroll.c
@@ -100,10 +100,6 @@ struct var_to_expand
the accumulator. If REUSE_EXPANSION is 0 reuse
the original accumulator. Else use
var_expansions[REUSE_EXPANSION - 1]. */
- unsigned accum_pos; /* The position in which the accumulator is placed in
- the insn src. For example in x = x + something
- accum_pos is 0 while in x = something + x accum_pos
- is 1. */
};
/* Information about optimization applied in
@@ -602,26 +598,21 @@ decide_unroll_constant_iterations (struct loop *loop, int flags)
}
}
- if (dump_file)
- fprintf (dump_file, ";; max_unroll %d (%d copies, initial %d).\n",
- best_unroll + 1, best_copies, nunroll);
-
loop->lpt_decision.decision = LPT_UNROLL_CONSTANT;
loop->lpt_decision.times = best_unroll;
if (dump_file)
- fprintf (dump_file,
- ";; Decided to unroll the constant times rolling loop, %d times.\n",
- loop->lpt_decision.times);
+ fprintf (dump_file, ";; Decided to unroll the loop %d times (%d copies).\n",
+ loop->lpt_decision.times, best_copies);
}
-/* Unroll LOOP with constant number of iterations LOOP->LPT_DECISION.TIMES + 1
- times. The transformation does this:
+/* Unroll LOOP with constant number of iterations LOOP->LPT_DECISION.TIMES times.
+ The transformation does this:
for (i = 0; i < 102; i++)
body;
- ==>
+ ==> (LOOP->LPT_DECISION.TIMES == 3)
i = 0;
body; i++;
@@ -671,7 +662,7 @@ unroll_loop_constant_iterations (struct loop *loop)
of exit condition have continuous body after unrolling. */
if (dump_file)
- fprintf (dump_file, ";; Condition on beginning of loop.\n");
+ fprintf (dump_file, ";; Condition at beginning of loop.\n");
/* Peel exit_mod iterations. */
RESET_BIT (wont_exit, 0);
@@ -713,7 +704,7 @@ unroll_loop_constant_iterations (struct loop *loop)
the loop tests the condition at the end of loop body. */
if (dump_file)
- fprintf (dump_file, ";; Condition on end of loop.\n");
+ fprintf (dump_file, ";; Condition at end of loop.\n");
/* We know that niter >= max_unroll + 2; so we do not need to care of
case when we would exit before reaching the loop. So just peel
@@ -896,9 +887,7 @@ decide_unroll_runtime_iterations (struct loop *loop, int flags)
loop->lpt_decision.times = i - 1;
if (dump_file)
- fprintf (dump_file,
- ";; Decided to unroll the runtime computable "
- "times rolling loop, %d times.\n",
+ fprintf (dump_file, ";; Decided to unroll the loop %d times.\n",
loop->lpt_decision.times);
}
@@ -949,14 +938,14 @@ split_edge_and_insert (edge e, rtx insns)
return bb;
}
-/* Unroll LOOP for that we are able to count number of iterations in runtime
- LOOP->LPT_DECISION.TIMES + 1 times. The transformation does this (with some
+/* Unroll LOOP for which we are able to count number of iterations in runtime
+ LOOP->LPT_DECISION.TIMES times. The transformation does this (with some
extra care for case n < 0):
for (i = 0; i < n; i++)
body;
- ==>
+ ==> (LOOP->LPT_DECISION.TIMES == 3)
i = 0;
mod = n % 4;
@@ -1314,20 +1303,23 @@ decide_peel_simple (struct loop *loop, int flags)
loop->lpt_decision.times = npeel;
if (dump_file)
- fprintf (dump_file, ";; Decided to simply peel the loop, %d times.\n",
+ fprintf (dump_file, ";; Decided to simply peel the loop %d times.\n",
loop->lpt_decision.times);
}
-/* Peel a LOOP LOOP->LPT_DECISION.TIMES times. The transformation:
+/* Peel a LOOP LOOP->LPT_DECISION.TIMES times. The transformation does this:
+
while (cond)
body;
- ==>
+ ==> (LOOP->LPT_DECISION.TIMES == 3)
if (!cond) goto end;
body;
if (!cond) goto end;
body;
+ if (!cond) goto end;
+ body;
while (cond)
body;
end: ;
@@ -1464,16 +1456,16 @@ decide_unroll_stupid (struct loop *loop, int flags)
loop->lpt_decision.times = i - 1;
if (dump_file)
- fprintf (dump_file,
- ";; Decided to unroll the loop stupidly, %d times.\n",
+ fprintf (dump_file, ";; Decided to unroll the loop stupidly %d times.\n",
loop->lpt_decision.times);
}
-/* Unroll a LOOP LOOP->LPT_DECISION.TIMES times. The transformation:
+/* Unroll a LOOP LOOP->LPT_DECISION.TIMES times. The transformation does this:
+
while (cond)
body;
- ==>
+ ==> (LOOP->LPT_DECISION.TIMES == 3)
while (cond)
{
@@ -1767,7 +1759,6 @@ analyze_insn_to_expand_var (struct loop *loop, rtx insn)
ves->op = GET_CODE (src);
ves->expansion_count = 0;
ves->reuse_expansion = 0;
- ves->accum_pos = accum_pos;
return ves;
}
@@ -2127,9 +2118,7 @@ expand_var_during_unrolling (struct var_to_expand *ve, rtx insn)
else
new_reg = get_expansion (ve);
- validate_change (insn, &SET_DEST (set), new_reg, 1);
- validate_change (insn, &XEXP (SET_SRC (set), ve->accum_pos), new_reg, 1);
-
+ validate_replace_rtx_group (SET_DEST (set), new_reg, insn);
if (apply_change_group ())
if (really_new_expansion)
{
@@ -2169,7 +2158,7 @@ static void
insert_var_expansion_initialization (struct var_to_expand *ve,
basic_block place)
{
- rtx seq, var, zero_init, insn;
+ rtx seq, var, zero_init;
unsigned i;
enum machine_mode mode = GET_MODE (ve->reg);
bool honor_signed_zero_p = HONOR_SIGNED_ZEROS (mode);
@@ -2209,11 +2198,7 @@ insert_var_expansion_initialization (struct var_to_expand *ve,
seq = get_insns ();
end_sequence ();
- insn = BB_HEAD (place);
- while (!NOTE_INSN_BASIC_BLOCK_P (insn))
- insn = NEXT_INSN (insn);
-
- emit_insn_after (seq, insn);
+ emit_insn_after (seq, BB_END (place));
}
/* Combine the variable expansions at the loop exit. PLACE is the
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 91215216f9d..a5d13eec5ff 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -138,8 +138,8 @@ clear_line_info (struct data_in *data_in)
/* Read a location bitpack from input block IB. */
-static location_t
-lto_input_location_bitpack (struct data_in *data_in, struct bitpack_d *bp)
+location_t
+lto_input_location (struct bitpack_d *bp, struct data_in *data_in)
{
bool file_change, line_change, column_change;
unsigned len;
@@ -178,26 +178,6 @@ lto_input_location_bitpack (struct data_in *data_in, struct bitpack_d *bp)
}
-/* Read a location from input block IB.
- If the input_location streamer hook exists, call it.
- Otherwise, proceed with reading the location from the
- expanded location bitpack. */
-
-location_t
-lto_input_location (struct lto_input_block *ib, struct data_in *data_in)
-{
- if (streamer_hooks.input_location)
- return streamer_hooks.input_location (ib, data_in);
- else
- {
- struct bitpack_d bp;
-
- bp = streamer_read_bitpack (ib);
- return lto_input_location_bitpack (data_in, &bp);
- }
-}
-
-
/* Read a reference to a tree node from DATA_IN using input block IB.
TAG is the expected node that should be found in IB, if TAG belongs
to one of the indexable trees, expect to read a reference index to
@@ -368,9 +348,13 @@ input_eh_region (struct lto_input_block *ib, struct data_in *data_in, int ix)
break;
case LTO_ert_must_not_throw:
- r->type = ERT_MUST_NOT_THROW;
- r->u.must_not_throw.failure_decl = stream_read_tree (ib, data_in);
- r->u.must_not_throw.failure_loc = lto_input_location (ib, data_in);
+ {
+ r->type = ERT_MUST_NOT_THROW;
+ r->u.must_not_throw.failure_decl = stream_read_tree (ib, data_in);
+ bitpack_d bp = streamer_read_bitpack (ib);
+ r->u.must_not_throw.failure_loc
+ = stream_input_location (&bp, data_in);
+ }
break;
default:
@@ -786,10 +770,6 @@ input_struct_function_base (struct function *fn, struct data_in *data_in,
}
}
- /* Input the function start and end loci. */
- fn->function_start_locus = lto_input_location (ib, data_in);
- fn->function_end_locus = lto_input_location (ib, data_in);
-
/* Input the current IL state of the function. */
fn->curr_properties = streamer_read_uhwi (ib);
@@ -809,6 +789,10 @@ input_struct_function_base (struct function *fn, struct data_in *data_in,
fn->calls_setjmp = bp_unpack_value (&bp, 1);
fn->va_list_fpr_size = bp_unpack_value (&bp, 8);
fn->va_list_gpr_size = bp_unpack_value (&bp, 8);
+
+ /* Input the function start and end loci. */
+ fn->function_start_locus = stream_input_location (&bp, data_in);
+ fn->function_end_locus = stream_input_location (&bp, data_in);
}
@@ -1041,7 +1025,7 @@ lto_read_tree (struct lto_input_block *ib, struct data_in *data_in,
/* Read all the bitfield values in RESULT. Note that for LTO, we
only write language-independent bitfields, so no more unpacking is
needed. */
- streamer_read_tree_bitfields (ib, result);
+ streamer_read_tree_bitfields (ib, data_in, result);
/* Read all the pointer fields in RESULT. */
streamer_read_tree_body (ib, data_in, result);
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index 083db74f911..55a20dd134b 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -148,10 +148,9 @@ tree_is_indexable (tree t)
After outputting bitpack, lto_output_location_data has
to be done to output actual data. */
-static inline void
-lto_output_location_bitpack (struct bitpack_d *bp,
- struct output_block *ob,
- location_t loc)
+void
+lto_output_location (struct output_block *ob, struct bitpack_d *bp,
+ location_t loc)
{
expanded_location xloc;
@@ -182,25 +181,6 @@ lto_output_location_bitpack (struct bitpack_d *bp,
}
-/* Emit location LOC to output block OB.
- If the output_location streamer hook exists, call it.
- Otherwise, when bitpack is handy, it is more space efficient to call
- lto_output_location_bitpack with existing bitpack. */
-
-void
-lto_output_location (struct output_block *ob, location_t loc)
-{
- if (streamer_hooks.output_location)
- streamer_hooks.output_location (ob, loc);
- else
- {
- struct bitpack_d bp = bitpack_create (ob->main_stream);
- lto_output_location_bitpack (&bp, ob, loc);
- streamer_write_bitpack (&bp);
- }
-}
-
-
/* If EXPR is an indexable tree node, output a reference to it to
output block OB. Otherwise, output the physical representation of
EXPR to OB. */
@@ -333,7 +313,7 @@ lto_write_tree (struct output_block *ob, tree expr, bool ref_p)
/* Pack all the non-pointer fields in EXPR into a bitpack and write
the resulting bitpack. */
bp = bitpack_create (ob->main_stream);
- streamer_pack_tree_bitfields (&bp, expr);
+ streamer_pack_tree_bitfields (ob, &bp, expr);
streamer_write_bitpack (&bp);
/* Write all the pointer fields in EXPR. */
@@ -505,7 +485,9 @@ output_eh_region (struct output_block *ob, eh_region r)
else if (r->type == ERT_MUST_NOT_THROW)
{
stream_write_tree (ob, r->u.must_not_throw.failure_decl, true);
- lto_output_location (ob, r->u.must_not_throw.failure_loc);
+ bitpack_d bp = bitpack_create (ob->main_stream);
+ stream_output_location (ob, &bp, r->u.must_not_throw.failure_loc);
+ streamer_write_bitpack (&bp);
}
if (r->landing_pads)
@@ -751,10 +733,6 @@ output_struct_function_base (struct output_block *ob, struct function *fn)
FOR_EACH_VEC_ELT (tree, fn->local_decls, i, t)
stream_write_tree (ob, t, true);
- /* Output the function start and end loci. */
- lto_output_location (ob, fn->function_start_locus);
- lto_output_location (ob, fn->function_end_locus);
-
/* Output current IL state of the function. */
streamer_write_uhwi (ob, fn->curr_properties);
@@ -774,6 +752,11 @@ output_struct_function_base (struct output_block *ob, struct function *fn)
bp_pack_value (&bp, fn->calls_setjmp, 1);
bp_pack_value (&bp, fn->va_list_fpr_size, 8);
bp_pack_value (&bp, fn->va_list_gpr_size, 8);
+
+ /* Output the function start and end loci. */
+ stream_output_location (ob, &bp, fn->function_start_locus);
+ stream_output_location (ob, &bp, fn->function_end_locus);
+
streamer_write_bitpack (&bp);
}
diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c
index 51c6658ec92..a338df0f28c 100644
--- a/gcc/lto-streamer.c
+++ b/gcc/lto-streamer.c
@@ -387,4 +387,6 @@ lto_streamer_hooks_init (void)
streamer_hooks_init ();
streamer_hooks.write_tree = lto_output_tree;
streamer_hooks.read_tree = lto_input_tree;
+ streamer_hooks.input_location = lto_input_location;
+ streamer_hooks.output_location = lto_output_location;
}
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index b2f8d30ff63..c7b7ef94871 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -809,7 +809,7 @@ extern struct data_in *lto_data_in_create (struct lto_file_decl_data *,
VEC(ld_plugin_symbol_resolution_t,heap) *);
extern void lto_data_in_delete (struct data_in *);
extern void lto_input_data_block (struct lto_input_block *, void *, size_t);
-location_t lto_input_location (struct lto_input_block *, struct data_in *);
+location_t lto_input_location (struct bitpack_d *, struct data_in *);
tree lto_input_tree_ref (struct lto_input_block *, struct data_in *,
struct function *, enum LTO_tags);
void lto_tag_check_set (enum LTO_tags, int, ...);
@@ -829,7 +829,7 @@ void lto_output_decl_state_streams (struct output_block *,
void lto_output_decl_state_refs (struct output_block *,
struct lto_output_stream *,
struct lto_out_decl_state *);
-void lto_output_location (struct output_block *, location_t);
+void lto_output_location (struct output_block *, struct bitpack_d *, location_t);
/* In lto-cgraph.c */
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index 265922f5d13..49b8af0235d 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,10 @@
+2012-10-12 Richard Biener <rguenther@suse.de>
+
+ PR lto/54898
+ * lto.c (gimple_types_compatible_p_1): Also compare
+ TYPE_MAIN_VARIANT.
+ (iterative_hash_gimple_type): Also hash TYPE_MAIN_VARIANT.
+
2012-10-09 Tobias Burnus <burnus@net-b.de>
* lto-lang.c (lto_register_builtin_type): Avoid useless
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 2b9156aebba..7f64daee219 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -581,6 +581,15 @@ gimple_types_compatible_p_1 (tree t1, tree t2, type_pair_t p,
if (!compare_type_names_p (t1, t2))
goto different_types;
+ /* The main variant of both types should compare equal. */
+ if (TYPE_MAIN_VARIANT (t1) != t1
+ || TYPE_MAIN_VARIANT (t2) != t2)
+ {
+ if (!gtc_visit (TYPE_MAIN_VARIANT (t1), TYPE_MAIN_VARIANT (t2),
+ state, sccstack, sccstate, sccstate_obstack))
+ goto different_types;
+ }
+
/* We may not merge typedef types to the same type in different
contexts. */
if (TYPE_NAME (t1)
@@ -1101,6 +1110,12 @@ iterative_hash_gimple_type (tree type, hashval_t val,
&& TYPE_P (DECL_CONTEXT (TYPE_NAME (type))))
v = visit (DECL_CONTEXT (TYPE_NAME (type)), state, v,
sccstack, sccstate, sccstate_obstack);
+
+ /* Factor in the variant structure. */
+ if (TYPE_MAIN_VARIANT (type) != type)
+ v = visit (TYPE_MAIN_VARIANT (type), state, v,
+ sccstack, sccstate, sccstate_obstack);
+
v = iterative_hash_hashval_t (TREE_CODE (type), v);
v = iterative_hash_hashval_t (TYPE_QUALS (type), v);
v = iterative_hash_hashval_t (TREE_ADDRESSABLE (type), v);
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 8a6c6a330b4..a63394d1312 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -6388,20 +6388,14 @@ get_rtx_code (enum tree_code tcode, bool unsignedp)
unsigned operators. Do not generate compare instruction. */
static rtx
-vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode)
+vector_compare_rtx (enum tree_code tcode, tree t_op0, tree t_op1,
+ bool unsignedp, enum insn_code icode)
{
struct expand_operand ops[2];
- enum rtx_code rcode;
- tree t_op0, t_op1;
rtx rtx_op0, rtx_op1;
+ enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
- /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer
- ensures that condition is a relational operation. */
- gcc_assert (COMPARISON_CLASS_P (cond));
-
- rcode = get_rtx_code (TREE_CODE (cond), unsignedp);
- t_op0 = TREE_OPERAND (cond, 0);
- t_op1 = TREE_OPERAND (cond, 1);
+ gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison);
/* Expand operands. */
rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
@@ -6684,11 +6678,26 @@ expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
enum machine_mode mode = TYPE_MODE (vec_cond_type);
enum machine_mode cmp_op_mode;
bool unsignedp;
+ tree op0a, op0b;
+ enum tree_code tcode;
- gcc_assert (COMPARISON_CLASS_P (op0));
+ if (COMPARISON_CLASS_P (op0))
+ {
+ op0a = TREE_OPERAND (op0, 0);
+ op0b = TREE_OPERAND (op0, 1);
+ tcode = TREE_CODE (op0);
+ }
+ else
+ {
+ /* Fake op0 < 0. */
+ gcc_assert (!TYPE_UNSIGNED (TREE_TYPE (op0)));
+ op0a = op0;
+ op0b = build_zero_cst (TREE_TYPE (op0));
+ tcode = LT_EXPR;
+ }
+ unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
+ cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a));
- unsignedp = TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0)));
- cmp_op_mode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (op0, 0)));
gcc_assert (GET_MODE_SIZE (mode) == GET_MODE_SIZE (cmp_op_mode)
&& GET_MODE_NUNITS (mode) == GET_MODE_NUNITS (cmp_op_mode));
@@ -6697,7 +6706,7 @@ expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
if (icode == CODE_FOR_nothing)
return 0;
- comparison = vector_compare_rtx (op0, unsignedp, icode);
+ comparison = vector_compare_rtx (tcode, op0a, op0b, unsignedp, icode);
rtx_op1 = expand_normal (op1);
rtx_op2 = expand_normal (op2);
diff --git a/gcc/optabs.def b/gcc/optabs.def
index 9f6b29cd3e5..b483b0274e7 100644
--- a/gcc/optabs.def
+++ b/gcc/optabs.def
@@ -306,3 +306,6 @@ OPTAB_D (atomic_sub_fetch_optab, "atomic_sub_fetch$I$a")
OPTAB_D (atomic_sub_optab, "atomic_sub$I$a")
OPTAB_D (atomic_xor_fetch_optab, "atomic_xor_fetch$I$a")
OPTAB_D (atomic_xor_optab, "atomic_xor$I$a")
+
+OPTAB_D (get_thread_pointer_optab, "get_thread_pointer$I$a")
+OPTAB_D (set_thread_pointer_optab, "set_thread_pointer$I$a")
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 95cf1860af0..cb63b80500e 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -668,7 +668,7 @@ simplify_truncation (enum machine_mode mode, rtx op,
&& CONST_INT_P (XEXP (op, 1))
&& GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
&& GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
- && INTVAL (XEXP (op, 1)) < precision)
+ && UINTVAL (XEXP (op, 1)) < precision)
return simplify_gen_binary (ASHIFTRT, mode,
XEXP (XEXP (op, 0), 0), XEXP (op, 1));
@@ -680,7 +680,7 @@ simplify_truncation (enum machine_mode mode, rtx op,
&& CONST_INT_P (XEXP (op, 1))
&& GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
&& GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
- && INTVAL (XEXP (op, 1)) < precision)
+ && UINTVAL (XEXP (op, 1)) < precision)
return simplify_gen_binary (LSHIFTRT, mode,
XEXP (XEXP (op, 0), 0), XEXP (op, 1));
@@ -692,7 +692,7 @@ simplify_truncation (enum machine_mode mode, rtx op,
&& (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
|| GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
&& GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
- && INTVAL (XEXP (op, 1)) < precision)
+ && UINTVAL (XEXP (op, 1)) < precision)
return simplify_gen_binary (ASHIFT, mode,
XEXP (XEXP (op, 0), 0), XEXP (op, 1));
@@ -705,8 +705,7 @@ simplify_truncation (enum machine_mode mode, rtx op,
&& 2 * precision <= op_precision
&& CONST_INT_P (XEXP (op, 1))
&& (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
- && INTVAL (XEXP (op, 1)) >= 0
- && INTVAL (XEXP (op, 1)) < op_precision)
+ && UINTVAL (XEXP (op, 1)) < op_precision)
{
int byte = subreg_lowpart_offset (mode, op_mode);
int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
diff --git a/gcc/streamer-hooks.h b/gcc/streamer-hooks.h
index d23d130cd3e..03de155d2dc 100644
--- a/gcc/streamer-hooks.h
+++ b/gcc/streamer-hooks.h
@@ -53,15 +53,11 @@ struct streamer_hooks {
tree instantiated from the stream. */
tree (*read_tree) (struct lto_input_block *, struct data_in *);
- /* [OPT] Called by lto_input_location to retrieve the source location of the
- tree currently being read. If this hook returns NULL, lto_input_location
- defaults to calling lto_input_location_bitpack. */
- location_t (*input_location) (struct lto_input_block *, struct data_in *);
-
- /* [OPT] Called by lto_output_location to write the source_location of the
- tree currently being written. If this hook returns NULL,
- lto_output_location defaults to calling lto_output_location_bitpack. */
- void (*output_location) (struct output_block *, location_t);
+ /* [REQ] Called by every streaming routine that needs to read a location. */
+ location_t (*input_location) (struct bitpack_d *, struct data_in *);
+
+ /* [REQ] Called by every streaming routine that needs to write a location. */
+ void (*output_location) (struct output_block *, struct bitpack_d *, location_t);
};
#define stream_write_tree(OB, EXPR, REF_P) \
@@ -73,6 +69,12 @@ struct streamer_hooks {
#define stream_read_tree(IB, DATA_IN) \
streamer_hooks.read_tree(IB, DATA_IN)
+#define stream_input_location(BP, DATA_IN) \
+ streamer_hooks.input_location(BP, DATA_IN)
+
+#define stream_output_location(OB, BP, LOC) \
+ streamer_hooks.output_location(OB, BP, LOC)
+
/* Streamer hooks. */
extern struct streamer_hooks streamer_hooks;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a5a27a87fd3..38055629b88 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,235 @@
+2012-10-15 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50080
+ * g++.dg/parse/tmpl-outside2.C: New.
+ * g++.dg/parse/tmpl-outside1.C: Adjust.
+ * g++.dg/template/qualttp18.C: Likewise.
+ * g++.old-deja/g++.pt/memtemp87.C: Likewise.
+ * g++.old-deja/g++.pt/overload13.C: Likewise.
+
+2012-10-15 Marc Glisse <marc.glisse@inria.fr>
+
+ PR tree-optimization/54915
+ * gcc.dg/tree-ssa/pr54915.c: New testcase.
+
+2012-10-15 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/54920
+ * gcc.dg/torture/pr54920.c: New testcase.
+
+2012-10-15 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/unchecked_convert9.ad[sb]: New test.
+
+2012-10-13 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/tls/thread_local7g.C: Require tls_native.
+
+2012-10-14 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/cpp0x/inh-ctor1.C: New.
+ * g++.dg/cpp0x/inh-ctor2.C: New.
+ * g++.dg/cpp0x/inh-ctor3.C: New.
+ * g++.dg/cpp0x/inh-ctor4.C: New.
+ * g++.dg/cpp0x/inh-ctor5.C: New.
+ * g++.dg/cpp0x/inh-ctor6.C: New.
+ * g++.dg/cpp0x/inh-ctor7.C: New.
+ * g++.dg/cpp0x/inh-ctor8.C: New.
+ * g++.dg/cpp0x/inh-ctor9.C: New.
+ * g++.dg/cpp0x/inh-ctor10.C: New.
+ * g++.dg/cpp0x/inh-ctor11.C: New.
+ * g++.dg/cpp0x/inh-ctor12.C: New.
+ * g++.dg/cpp0x/inh-ctor13.C: New.
+
+2012-10-14 Steven Bosscher <steven@gcc.gnu.org>
+
+ PR rtl-optimization/54919
+ * gcc.dg/pr54919.c: New testcase.
+
+2012-10-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53581
+ * g++.dg/template/crash113.C: New.
+
+2012-10-14 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/unroll_5.c: New testcase.
+
+2012-10-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52643
+ * g++.dg/opt/pr52643.C: New.
+
+2012-10-12 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54602
+ * gcc.target/sh/pr54602-1.c: New.
+ * gcc.target/sh/pr54602-2.c: New.
+ * gcc.target/sh/pr54602-3.c: New.
+ * gcc.target/sh/pr54602-4.c: New.
+
+2012-10-12 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54680
+ * gcc.target/sh/pr54680.c: New.
+
+2012-10-12 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/webizer.c: New testcase.
+
+2012-10-12 Janis Johnson <janisjo@codesourcery.com>
+
+ * gcc.dg/vect/pr48765.c: Skip for conflicting options, don't
+ specify -m64.
+
+ * gcc.target/arm/div64-unwinding.c: Skip, don't xfail, for
+ GNU/Linux.
+
+ * lib/target-supports.exp (check_effective_target_arm_hard_vfp_ok):
+ Return 0 if already specifying -mfloat-abi other than hard.
+
+2012-10-12 Joe Seymour <jseymour@codesourcery.com>
+
+ * gcc.dg/pr53060.c: Prune irrelevant warning.
+
+2012-10-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/54381
+ * c-c++-common/Wsizeof-pointer-memaccess1.c: New test.
+ * c-c++-common/Wsizeof-pointer-memaccess2.c: New test.
+ * gcc.dg/Wsizeof-pointer-memaccess1.c: New test.
+ * gcc.dg/torture/Wsizeof-pointer-memaccess1.c: Test also stpncpy.
+ Adjust expected wording of warnings for *cmp* builtins.
+ * g++.dg/torture/Wsizeof-pointer-memaccess1.C: Likewise.
+ * g++.dg/torture/Wsizeof-pointer-memaccess2.C: Likewise.
+
+2012-10-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/24449
+ * g++.dg/parse/friend-main.C: New.
+
+2012-10-12 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/53055
+ * g++.dg/pr53055.C: New testcase.
+
+2012-10-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52744
+ * g++.dg/cpp0x/pr52744.C: New.
+
+2012-10-12 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/40453
+ * gfortran.dg/dummy_procedure_9.f90: New.
+
+2012-10-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/54894
+ * gcc.dg/torture/pr54894.c: New testcase.
+
+2012-10-12 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/51244
+ * gcc.target/sh/pr51244-13.c: New.
+ * gcc.target/sh/pr51244-14.c: New.
+ * gcc.target/sh/pr51244-15.c: New.
+ * gcc.target/sh/pr51244-16.c: New.
+
+2012-10-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51878
+ * g++.dg/cpp0x/decltype45.C: New.
+
+2012-10-11 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/54784
+ * gfortran.dg/class_allocate_13.f90: New.
+
+2012-10-11 Jason Merrill <jason@redhat.com>
+
+ * g++.dg/ext/visibility/pragma-override1.C: Fix target markup.
+ * g++.dg/ext/visibility/pragma-override2.C: Fix target markup.
+
+ * g++.dg/gomp/tls-5.C: Require tls_native.
+ * g++.dg/tls/thread_local7.C: Require tls_native.
+ * g++.dg/tls/static2.C: New.
+
+2012-10-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/36107
+ * g++.dg/ext/weak5.C: New.
+
+2012-10-11 Marc Glisse <marc.glisse@inria.fr>
+
+ PR testsuite/54868
+ * gcc.dg/tree-ssa/forwprop-22.c: Move ...
+ * gcc.dg/vect/nodump-forwprop-22.c: ... here. Adapt options.
+
+2012-10-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/43765
+ * g++.dg/parse/pr43765.C: New.
+
+2012-10-11 Uros Bizjak <ubizjak@gmail.com>
+
+ * obj-c++.dg/tls/init-2.mm: Tweak errors.
+
+2012-10-10 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/43663
+ * g++.dg/init/bitfield3.C: New.
+
+2012-10-10 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * gcc.target/mips/mips32-dsp-accinit-2.c: Fix test description.
+
+2012-10-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/54877
+ * gcc.dg/torture/pr54877.c: New test.
+
+2012-10-10 Venkataramanan Kumar <venkataramanan.kumar@amd.com>
+
+ PR testsuite/53397
+ * gcc.dg/pr53397-1.c: Moved to gcc.target/i386.
+ * gcc.target/i386/pr53397-1.c: Add -msse2 to dg-options
+ and remove target info from dg-do compile.
+ * gcc.dg/pr53397-2.c: Moved to gcc.target/i386.
+ * gcc.target/i386/pr53397-2.c: Add -msse2 to dg-options
+ and remove target info from dg-do compile.
+
+2012-10-10 Greta Yorsh <Greta.Yorsh@arm.com>
+
+ * gcc.dg/pr54782.c: Require target with pthread support.
+
+2012-10-10 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53122
+ * g++.dg/cpp0x/auto35.C: New.
+
+2012-10-10 Dodji Seketeli <dodji@redhat.com>
+
+ PR c++/53540 - using fails to be equivalent to typedef
+ * g++.dg/cpp0x/alias-decl-24.C: New test.
+
+2012-10-10 Dodji Seketeli <dodji@redhat.com>
+
+ * g++.dg/cpp0x/gen-attrs-8.C: Update the test to reflect the fact
+ that c++11 attributes to types are ignored for now.
+ * g++.dg/cpp0x/gen-attrs-36.C: Likewise.
+ * g++.dg/cpp0x/gen-attrs-37.C: Likewise
+
+2012-10-10 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53741
+ * g++.dg/cpp0x/lambda/lambda-ice9.C: New.
+
+2012-10-10 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50478
+ * g++.dg/cpp0x/initlist67.C: New.
+
2012-10-10 Dehao Chen <dehao@google.com>
* g++.dg/debug/dwarf2/deallocator.C: Cover more deallocator cases.
@@ -109,6 +341,11 @@
* g++.dg/tls/thread_local2.C: New.
* g++.dg/tls/thread_local7.C: New.
+2012-10-09 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ PR target/54866
+ * gcc.target/i386/long-double-80-7.c: Add -msse2 to dg-options.
+
2012-10-08 Oleg Endo <olegendo@gcc.gnu.org>
PR target/54685
diff --git a/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess1.c b/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess1.c
new file mode 100644
index 00000000000..2a5f4193b21
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess1.c
@@ -0,0 +1,161 @@
+/* Test -Wsizeof-pointer-memaccess warnings. */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+typedef __SIZE_TYPE__ size_t;
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern int snprintf (char *, size_t, const char *, ...);
+extern int vsnprintf (char *, size_t, const char *, __builtin_va_list);
+extern void *memchr (const void *, int, size_t);
+#ifdef __cplusplus
+}
+#endif
+
+struct A { short a, b; int c, d; long e, f; };
+typedef struct A TA;
+typedef struct A *PA;
+typedef TA *PTA;
+struct B {};
+typedef struct B TB;
+typedef struct B *PB;
+typedef TB *PTB;
+typedef int X[3][3][3];
+
+void foo (void **);
+
+void
+f1 (void *x)
+{
+ struct A a, *pa1 = &a;
+ TA *pa2 = &a;
+ PA pa3 = &a;
+ PTA pa4 = &a;
+ void *arr[100];
+ int i = 0;
+ arr[i++] = memchr (&a, 0, sizeof (&a)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ arr[i++] = memchr (pa1, 0, sizeof (pa1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ arr[i++] = memchr (pa2, 0, sizeof pa2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ arr[i++] = memchr (pa3, 0, sizeof (pa3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ arr[i++] = memchr (pa4, 0, sizeof pa4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ arr[i++] = memchr (pa1, 0, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ arr[i++] = memchr (pa2, 0, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ arr[i++] = memchr (pa3, 0, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ arr[i++] = memchr (pa4, 0, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+
+ /* These are correct, no warning. */
+ arr[i++] = memchr (&a, 0, sizeof a);
+ arr[i++] = memchr (&a, 0, sizeof (a));
+ arr[i++] = memchr (&a, 0, sizeof (struct A));
+ arr[i++] = memchr (&a, 0, sizeof (const struct A));
+ arr[i++] = memchr (&a, 0, sizeof (volatile struct A));
+ arr[i++] = memchr (&a, 0, sizeof (volatile const struct A));
+ arr[i++] = memchr (&a, 0, sizeof (TA));
+ arr[i++] = memchr (&a, 0, sizeof (__typeof (*&a)));
+ arr[i++] = memchr (pa1, 0, sizeof (*pa1));
+ arr[i++] = memchr (pa2, 0, sizeof (*pa3));
+ arr[i++] = memchr (pa3, 0, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ arr[i++] = memchr ((void *) &a, 0, sizeof (&a));
+ arr[i++] = memchr ((char *) &a, 0, sizeof (&a));
+ arr[i++] = memchr (&a, 0, sizeof (&a) + 0);
+ arr[i++] = memchr (&a, 0, 0 + sizeof (&a));
+
+ foo (arr);
+}
+
+void
+f2 (void *x)
+{
+ struct B b, *pb1 = &b;
+ TB *pb2 = &b;
+ PB pb3 = &b;
+ PTB pb4 = &b;
+ void *arr[100];
+ int i = 0;
+ arr[i++] = memchr (&b, 0, sizeof (&b)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ arr[i++] = memchr (pb1, 0, sizeof (pb1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ arr[i++] = memchr (pb2, 0, sizeof pb2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ arr[i++] = memchr (pb3, 0, sizeof (pb3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ arr[i++] = memchr (pb4, 0, sizeof pb4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ arr[i++] = memchr (pb1, 0, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ arr[i++] = memchr (pb2, 0, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ arr[i++] = memchr (pb3, 0, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ arr[i++] = memchr (pb4, 0, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+
+ /* These are correct, no warning. */
+ arr[i++] = memchr (&b, 0, sizeof b);
+ arr[i++] = memchr (&b, 0, sizeof (b));
+ arr[i++] = memchr (&b, 0, sizeof (struct B));
+ arr[i++] = memchr (&b, 0, sizeof (const struct B));
+ arr[i++] = memchr (&b, 0, sizeof (volatile struct B));
+ arr[i++] = memchr (&b, 0, sizeof (volatile const struct B));
+ arr[i++] = memchr (&b, 0, sizeof (TB));
+ arr[i++] = memchr (&b, 0, sizeof (__typeof (*&b)));
+ arr[i++] = memchr (pb1, 0, sizeof (*pb1));
+ arr[i++] = memchr (pb2, 0, sizeof (*pb3));
+ arr[i++] = memchr (pb3, 0, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ arr[i++] = memchr ((void *) &b, 0, sizeof (&b));
+ arr[i++] = memchr ((char *) &b, 0, sizeof (&b));
+ arr[i++] = memchr (&b, 0, sizeof (&b) + 0);
+ arr[i++] = memchr (&b, 0, 0 + sizeof (&b));
+
+ foo (arr);
+}
+
+void
+f3 (void *x, char *y, int z, X w)
+{
+ unsigned char *y1 = (unsigned char *) __builtin_alloca (z + 16);
+ char buf1[7];
+ signed char buf2[z + 32];
+ long buf3[17];
+ int *buf4[9];
+ signed char *y2 = buf2;
+ char c;
+ void *arr[100];
+ int i = 0;
+ arr[i++] = memchr (y, 0, sizeof (y)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ arr[i++] = memchr (y1, 0, sizeof (y1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ arr[i++] = memchr (y2, 0, sizeof (y2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ arr[i++] = memchr (&c, 0, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ arr[i++] = memchr (w, 0, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+
+ /* These are correct, no warning. */
+ arr[i++] = memchr (y, 0, sizeof (*y));
+ arr[i++] = memchr (y1, 0, sizeof (*y2));
+ arr[i++] = memchr (buf1, 0, sizeof buf1);
+ arr[i++] = memchr (buf3, 0, sizeof (buf3));
+ arr[i++] = memchr (&buf3[0], 0, sizeof (buf3));
+ arr[i++] = memchr (&buf4[0], 0, sizeof (buf4));
+ arr[i++] = memchr (w, 0, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ arr[i++] = memchr ((void *) y, 0, sizeof (y));
+ arr[i++] = memchr ((char *) y1, 0, sizeof (y2));
+ arr[i++] = memchr (y, 0, sizeof (y) + 0);
+ arr[i++] = memchr (y1, 0, 0 + sizeof (y2));
+ arr[i++] = memchr ((void *) &c, 0, sizeof (&c));
+ arr[i++] = memchr ((signed char *) &c, 0, sizeof (&c));
+ arr[i++] = memchr (&c, 0, sizeof (&c) + 0);
+ arr[i++] = memchr (&c, 0, 0 + sizeof (&c));
+
+ foo (arr);
+}
+
+void
+f4 (char x[64], char *y, __builtin_va_list ap)
+{
+ char buf[128], *p = buf;
+ snprintf (x, sizeof (x), "%s", y); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ vsnprintf (x, sizeof (x), "%s", ap); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ snprintf (p, sizeof (p), "%s", y); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ vsnprintf (p, sizeof (p), "%s", ap); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+
+ /* These are correct, no warning. */
+ snprintf (buf, sizeof (buf), "%s", y);
+ vsnprintf (buf, sizeof (buf), "%s", ap);
+ snprintf (p, sizeof (buf), "%s", y);
+ vsnprintf (p, sizeof (buf), "%s", ap);
+}
diff --git a/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess2.c b/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess2.c
new file mode 100644
index 00000000000..73cdf0eaba7
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wsizeof-pointer-memaccess2.c
@@ -0,0 +1,482 @@
+/* Test -Wsizeof-pointer-memaccess warnings. */
+/* { dg-do compile } */
+/* { dg-options "-Wall -O2" } */
+
+#define bos(ptr) __builtin_object_size (ptr, 1)
+#define bos0(ptr) __builtin_object_size (ptr, 0)
+
+#define memset(dst, val, sz) __builtin___memset_chk (dst, val, sz, bos (dst))
+#define memcpy(dst, src, sz) __builtin___memcpy_chk (dst, src, sz, bos (dst))
+#define memmove(dst, src, sz) __builtin___memmove_chk (dst, src, sz, bos (dst))
+#define strncpy(dst, src, sz) __builtin___strncpy_chk (dst, src, sz, bos (dst))
+#define strncat(dst, src, sz) __builtin___strncat_chk (dst, src, sz, bos (dst))
+#define stpncpy(dst, src, sz) __builtin___stpncpy_chk (dst, src, sz, bos (dst))
+
+struct A { short a, b; int c, d; long e, f; };
+typedef struct A TA;
+typedef struct A *PA;
+typedef TA *PTA;
+struct B {};
+typedef struct B TB;
+typedef struct B *PB;
+typedef TB *PTB;
+typedef int X[3][3][3];
+
+void
+f1 (void *x)
+{
+ struct A a, *pa1 = &a;
+ TA *pa2 = &a;
+ PA pa3 = &a;
+ PTA pa4 = &a;
+ memset (&a, 0, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memset (pa1, 0, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memset (pa2, 0, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memset (pa3, 0, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memset (pa4, 0, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memset (pa1, 0, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memset (pa2, 0, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memset (pa3, 0, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memset (pa4, 0, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ memcpy (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memcpy (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memcpy (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memcpy (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memcpy (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memcpy (pa1, x, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (pa4, x, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ memcpy (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ memcpy (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memcpy (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memcpy (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memcpy (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memcpy (x, pa1, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (x, pa4, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+
+ memmove (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memmove (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memmove (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memmove (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memmove (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memmove (pa1, x, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memmove (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memmove (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memmove (pa4, x, sizeof (__typeof (pa4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ memmove (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ memmove (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memmove (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memmove (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memmove (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memmove (x, pa1, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memmove (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memmove (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memmove (x, pa4, sizeof (__typeof (pa4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+
+ /* These are correct, no warning. */
+ memset (&a, 0, sizeof a);
+ memset (&a, 0, sizeof (a));
+ memset (&a, 0, sizeof (struct A));
+ memset (&a, 0, sizeof (const struct A));
+ memset (&a, 0, sizeof (volatile struct A));
+ memset (&a, 0, sizeof (volatile const struct A));
+ memset (&a, 0, sizeof (TA));
+ memset (&a, 0, sizeof (__typeof (*&a)));
+ memset (pa1, 0, sizeof (*pa1));
+ memset (pa2, 0, sizeof (*pa3));
+ memset (pa3, 0, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memset ((void *) &a, 0, sizeof (&a));
+ memset ((char *) &a, 0, sizeof (&a));
+ memset (&a, 0, sizeof (&a) + 0);
+ memset (&a, 0, 0 + sizeof (&a));
+
+ /* These are correct, no warning. */
+ memcpy (&a, x, sizeof a);
+ memcpy (&a, x, sizeof (a));
+ memcpy (&a, x, sizeof (struct A));
+ memcpy (&a, x, sizeof (const struct A));
+ memcpy (&a, x, sizeof (volatile struct A));
+ memcpy (&a, x, sizeof (volatile const struct A));
+ memcpy (&a, x, sizeof (TA));
+ memcpy (&a, x, sizeof (__typeof (*&a)));
+ memcpy (pa1, x, sizeof (*pa1));
+ memcpy (pa2, x, sizeof (*pa3));
+ memcpy (pa3, x, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memcpy ((void *) &a, x, sizeof (&a));
+ memcpy ((char *) &a, x, sizeof (&a));
+ memcpy (&a, x, sizeof (&a) + 0);
+ memcpy (&a, x, 0 + sizeof (&a));
+
+ /* These are correct, no warning. */
+ memcpy (x, &a, sizeof a);
+ memcpy (x, &a, sizeof (a));
+ memcpy (x, &a, sizeof (struct A));
+ memcpy (x, &a, sizeof (const struct A));
+ memcpy (x, &a, sizeof (volatile struct A));
+ memcpy (x, &a, sizeof (volatile const struct A));
+ memcpy (x, &a, sizeof (TA));
+ memcpy (x, &a, sizeof (__typeof (*&a)));
+ memcpy (x, pa1, sizeof (*pa1));
+ memcpy (x, pa2, sizeof (*pa3));
+ memcpy (x, pa3, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memcpy (x, (void *) &a, sizeof (&a));
+ memcpy (x, (char *) &a, sizeof (&a));
+ memcpy (x, &a, sizeof (&a) + 0);
+ memcpy (x, &a, 0 + sizeof (&a));
+
+ /* These are correct, no warning. */
+ memmove (&a, x, sizeof a);
+ memmove (&a, x, sizeof (a));
+ memmove (&a, x, sizeof (struct A));
+ memmove (&a, x, sizeof (const struct A));
+ memmove (&a, x, sizeof (volatile struct A));
+ memmove (&a, x, sizeof (volatile const struct A));
+ memmove (&a, x, sizeof (TA));
+ memmove (&a, x, sizeof (__typeof (*&a)));
+ memmove (pa1, x, sizeof (*pa1));
+ memmove (pa2, x, sizeof (*pa3));
+ memmove (pa3, x, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memmove ((void *) &a, x, sizeof (&a));
+ memmove ((char *) &a, x, sizeof (&a));
+ memmove (&a, x, sizeof (&a) + 0);
+ memmove (&a, x, 0 + sizeof (&a));
+
+ /* These are correct, no warning. */
+ memmove (x, &a, sizeof a);
+ memmove (x, &a, sizeof (a));
+ memmove (x, &a, sizeof (struct A));
+ memmove (x, &a, sizeof (const struct A));
+ memmove (x, &a, sizeof (volatile struct A));
+ memmove (x, &a, sizeof (volatile const struct A));
+ memmove (x, &a, sizeof (TA));
+ memmove (x, &a, sizeof (__typeof (*&a)));
+ memmove (x, pa1, sizeof (*pa1));
+ memmove (x, pa2, sizeof (*pa3));
+ memmove (x, pa3, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memmove (x, (void *) &a, sizeof (&a));
+ memmove (x, (char *) &a, sizeof (&a));
+ memmove (x, &a, sizeof (&a) + 0);
+ memmove (x, &a, 0 + sizeof (&a));
+}
+
+void
+f2 (void *x)
+{
+ struct B b, *pb1 = &b;
+ TB *pb2 = &b;
+ PB pb3 = &b;
+ PTB pb4 = &b;
+ memset (&b, 0, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memset (pb1, 0, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memset (pb2, 0, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memset (pb3, 0, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memset (pb4, 0, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memset (pb1, 0, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memset (pb2, 0, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memset (pb3, 0, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memset (pb4, 0, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ memcpy (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memcpy (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memcpy (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memcpy (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memcpy (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memcpy (pb1, x, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (pb4, x, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ memcpy (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ memcpy (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memcpy (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memcpy (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memcpy (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memcpy (x, pb1, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memcpy (x, pb4, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+
+ memmove (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memmove (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memmove (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memmove (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memmove (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ memmove (pb1, x, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memmove (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memmove (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ memmove (pb4, x, sizeof (__typeof (pb4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ memmove (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ memmove (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memmove (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memmove (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memmove (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ memmove (x, pb1, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memmove (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memmove (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ memmove (x, pb4, sizeof (__typeof (pb4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+
+ /* These are correct, no warning. */
+ memset (&b, 0, sizeof b);
+ memset (&b, 0, sizeof (b));
+ memset (&b, 0, sizeof (struct B));
+ memset (&b, 0, sizeof (const struct B));
+ memset (&b, 0, sizeof (volatile struct B));
+ memset (&b, 0, sizeof (volatile const struct B));
+ memset (&b, 0, sizeof (TB));
+ memset (&b, 0, sizeof (__typeof (*&b)));
+ memset (pb1, 0, sizeof (*pb1));
+ memset (pb2, 0, sizeof (*pb3));
+ memset (pb3, 0, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memset ((void *) &b, 0, sizeof (&b));
+ memset ((char *) &b, 0, sizeof (&b));
+ memset (&b, 0, sizeof (&b) + 0);
+ memset (&b, 0, 0 + sizeof (&b));
+
+ /* These are correct, no warning. */
+ memcpy (&b, x, sizeof b);
+ memcpy (&b, x, sizeof (b));
+ memcpy (&b, x, sizeof (struct B));
+ memcpy (&b, x, sizeof (const struct B));
+ memcpy (&b, x, sizeof (volatile struct B));
+ memcpy (&b, x, sizeof (volatile const struct B));
+ memcpy (&b, x, sizeof (TB));
+ memcpy (&b, x, sizeof (__typeof (*&b)));
+ memcpy (pb1, x, sizeof (*pb1));
+ memcpy (pb2, x, sizeof (*pb3));
+ memcpy (pb3, x, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memcpy ((void *) &b, x, sizeof (&b));
+ memcpy ((char *) &b, x, sizeof (&b));
+ memcpy (&b, x, sizeof (&b) + 0);
+ memcpy (&b, x, 0 + sizeof (&b));
+
+ /* These are correct, no warning. */
+ memcpy (x, &b, sizeof b);
+ memcpy (x, &b, sizeof (b));
+ memcpy (x, &b, sizeof (struct B));
+ memcpy (x, &b, sizeof (const struct B));
+ memcpy (x, &b, sizeof (volatile struct B));
+ memcpy (x, &b, sizeof (volatile const struct B));
+ memcpy (x, &b, sizeof (TB));
+ memcpy (x, &b, sizeof (__typeof (*&b)));
+ memcpy (x, pb1, sizeof (*pb1));
+ memcpy (x, pb2, sizeof (*pb3));
+ memcpy (x, pb3, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memcpy (x, (void *) &b, sizeof (&b));
+ memcpy (x, (char *) &b, sizeof (&b));
+ memcpy (x, &b, sizeof (&b) + 0);
+ memcpy (x, &b, 0 + sizeof (&b));
+
+ /* These are correct, no warning. */
+ memmove (&b, x, sizeof b);
+ memmove (&b, x, sizeof (b));
+ memmove (&b, x, sizeof (struct B));
+ memmove (&b, x, sizeof (const struct B));
+ memmove (&b, x, sizeof (volatile struct B));
+ memmove (&b, x, sizeof (volatile const struct B));
+ memmove (&b, x, sizeof (TB));
+ memmove (&b, x, sizeof (__typeof (*&b)));
+ memmove (pb1, x, sizeof (*pb1));
+ memmove (pb2, x, sizeof (*pb3));
+ memmove (pb3, x, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memmove ((void *) &b, x, sizeof (&b));
+ memmove ((char *) &b, x, sizeof (&b));
+ memmove (&b, x, sizeof (&b) + 0);
+ memmove (&b, x, 0 + sizeof (&b));
+
+ /* These are correct, no warning. */
+ memmove (x, &b, sizeof b);
+ memmove (x, &b, sizeof (b));
+ memmove (x, &b, sizeof (struct B));
+ memmove (x, &b, sizeof (const struct B));
+ memmove (x, &b, sizeof (volatile struct B));
+ memmove (x, &b, sizeof (volatile const struct B));
+ memmove (x, &b, sizeof (TB));
+ memmove (x, &b, sizeof (__typeof (*&b)));
+ memmove (x, pb1, sizeof (*pb1));
+ memmove (x, pb2, sizeof (*pb3));
+ memmove (x, pb3, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ memmove (x, (void *) &b, sizeof (&b));
+ memmove (x, (char *) &b, sizeof (&b));
+ memmove (x, &b, sizeof (&b) + 0);
+ memmove (x, &b, 0 + sizeof (&b));
+}
+
+void
+f3 (void *x, char *y, int z, X w)
+{
+ unsigned char *y1 = (unsigned char *) __builtin_alloca (z + 16);
+ char buf1[7];
+ signed char buf2[z + 32];
+ long buf3[17];
+ int *buf4[9];
+ signed char *y2 = buf2;
+ char c;
+ char *y3;
+ memset (y, 0, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memset (y1, 0, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memset (y2, 0, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memset (&c, 0, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memset (w, 0, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+
+ memcpy (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memcpy (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memcpy (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memcpy (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memcpy (w, x, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+
+ memcpy (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ memcpy (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ memcpy (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ memcpy (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ memcpy (x, w, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+
+ memmove (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memmove (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memmove (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ memmove (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ memmove (w, x, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+
+ memmove (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ memmove (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ memmove (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ memmove (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ memmove (x, w, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+
+ /* These are correct, no warning. */
+ memset (y, 0, sizeof (*y));
+ memset (y1, 0, sizeof (*y2));
+ memset (buf1, 0, sizeof buf1);
+ memset (buf3, 0, sizeof (buf3));
+ memset (&buf3[0], 0, sizeof (buf3));
+ memset (&buf4[0], 0, sizeof (buf4));
+ memset (w, 0, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ memset ((void *) y, 0, sizeof (y));
+ memset ((char *) y1, 0, sizeof (y2));
+ memset (y, 0, sizeof (y) + 0);
+ memset (y1, 0, 0 + sizeof (y2));
+ memset ((void *) &c, 0, sizeof (&c));
+ memset ((signed char *) &c, 0, sizeof (&c));
+ memset (&c, 0, sizeof (&c) + 0);
+ memset (&c, 0, 0 + sizeof (&c));
+
+ /* These are correct, no warning. */
+ memcpy (y, x, sizeof (*y));
+ memcpy (y1, x, sizeof (*y2));
+ memcpy (buf1, x, sizeof buf1);
+ memcpy (buf3, x, sizeof (buf3));
+ memcpy (&buf3[0], x, sizeof (buf3));
+ memcpy (&buf4[0], x, sizeof (buf4));
+ memcpy (&y3, y, sizeof (y3));
+ memcpy ((char *) &y3, y, sizeof (y3));
+ memcpy (w, x, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ memcpy ((void *) y, x, sizeof (y));
+ memcpy ((char *) y1, x, sizeof (y2));
+ memcpy (y, x, sizeof (y) + 0);
+ memcpy (y1, x, 0 + sizeof (y2));
+ memcpy ((void *) &c, x, sizeof (&c));
+ memcpy ((signed char *) &c, x, sizeof (&c));
+ memcpy (&c, x, sizeof (&c) + 0);
+ memcpy (&c, x, 0 + sizeof (&c));
+
+ /* These are correct, no warning. */
+ memcpy (x, y, sizeof (*y));
+ memcpy (x, y1, sizeof (*y2));
+ memcpy (x, buf1, sizeof buf1);
+ memcpy (x, buf3, sizeof (buf3));
+ memcpy (x, &buf3[0], sizeof (buf3));
+ memcpy (x, &buf4[0], sizeof (buf4));
+ memcpy (y, &y3, sizeof (y3));
+ memcpy (y, (char *) &y3, sizeof (y3));
+ memcpy (x, w, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ memcpy (x, (void *) y, sizeof (y));
+ memcpy (x, (char *) y1, sizeof (y2));
+ memcpy (x, y, sizeof (y) + 0);
+ memcpy (x, y1, 0 + sizeof (y2));
+ memcpy (x, (void *) &c, sizeof (&c));
+ memcpy (x, (signed char *) &c, sizeof (&c));
+ memcpy (x, &c, sizeof (&c) + 0);
+ memcpy (x, &c, 0 + sizeof (&c));
+
+ /* These are correct, no warning. */
+ memmove (y, x, sizeof (*y));
+ memmove (y1, x, sizeof (*y2));
+ memmove (buf1, x, sizeof buf1);
+ memmove (buf3, x, sizeof (buf3));
+ memmove (&buf3[0], x, sizeof (buf3));
+ memmove (&buf4[0], x, sizeof (buf4));
+ memmove (&y3, y, sizeof (y3));
+ memmove ((char *) &y3, y, sizeof (y3));
+ memmove (w, x, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ memmove ((void *) y, x, sizeof (y));
+ memmove ((char *) y1, x, sizeof (y2));
+ memmove (y, x, sizeof (y) + 0);
+ memmove (y1, x, 0 + sizeof (y2));
+ memmove ((void *) &c, x, sizeof (&c));
+ memmove ((signed char *) &c, x, sizeof (&c));
+ memmove (&c, x, sizeof (&c) + 0);
+ memmove (&c, x, 0 + sizeof (&c));
+
+ /* These are correct, no warning. */
+ memmove (x, y, sizeof (*y));
+ memmove (x, y1, sizeof (*y2));
+ memmove (x, buf1, sizeof buf1);
+ memmove (x, buf3, sizeof (buf3));
+ memmove (x, &buf3[0], sizeof (buf3));
+ memmove (x, &buf4[0], sizeof (buf4));
+ memmove (y, &y3, sizeof (y3));
+ memmove (y, (char *) &y3, sizeof (y3));
+ memmove (x, w, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ memmove (x, (void *) y, sizeof (y));
+ memmove (x, (char *) y1, sizeof (y2));
+ memmove (x, y, sizeof (y) + 0);
+ memmove (x, y1, 0 + sizeof (y2));
+ memmove (x, (void *) &c, sizeof (&c));
+ memmove (x, (signed char *) &c, sizeof (&c));
+ memmove (x, &c, sizeof (&c) + 0);
+ memmove (x, &c, 0 + sizeof (&c));
+}
+
+void
+f4 (char *x, char **y, int z, char w[64])
+{
+ const char *s1 = "foobarbaz";
+ const char *s2 = "abcde12345678";
+ strncpy (x, s1, sizeof (s1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ strncat (x, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ stpncpy (x, s1, sizeof (s1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+
+ strncpy (w, s1, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ strncat (w, s2, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ stpncpy (w, s1, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+
+ /* These are correct, no warning. */
+ const char s3[] = "foobarbaz";
+ const char s4[] = "abcde12345678";
+ strncpy (x, s3, sizeof (s3));
+ strncat (x, s4, sizeof (s4));
+ stpncpy (x, s3, sizeof (s3));
+}
+
+/* { dg-prune-output "\[\n\r\]*will always overflow\[\n\r\]*" } */
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-24.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-24.C
new file mode 100644
index 00000000000..b68fa9346b4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-24.C
@@ -0,0 +1,24 @@
+// Origin: PR c++/53540
+// { dg-do compile { target c++11 } }
+
+template <typename T>
+struct context
+{
+ typedef int type;
+};
+
+template <typename T>
+void function()
+{
+ using ctx1 = context<T>;
+ typename ctx1::type f1;
+
+ typedef context<T> ctx2;
+ typename ctx2::type f2;
+}
+
+int main()
+{
+ function<int>();
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto35.C b/gcc/testsuite/g++.dg/cpp0x/auto35.C
new file mode 100644
index 00000000000..55eebbeffed
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/auto35.C
@@ -0,0 +1,11 @@
+// PR c++/53122
+// { dg-do compile { target c++11 } }
+
+template<typename... Args>
+ void foo(Args&&...) { }
+
+template<typename... Args>
+ void bar(Args&&...)
+{
+ auto fn = foo<Args...>;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype45.C b/gcc/testsuite/g++.dg/cpp0x/decltype45.C
new file mode 100644
index 00000000000..f768d8554e1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype45.C
@@ -0,0 +1,40 @@
+// PR c++/51878
+// { dg-do compile { target c++11 } }
+
+template<class F, class... T>
+auto indirect_call(F f, T... t) -> decltype(f(t...))
+{
+ return f(t...);
+}
+
+template<class F, class T>
+struct VariadicBind
+{
+ F f;
+ T t;
+
+ template<class... A>
+ auto operator()(A... a) -> decltype(indirect_call(f, t, a...))
+ {
+ return indirect_call(f, t, a...);
+ }
+};
+
+template<class F>
+void apply(F f)
+{
+ f();
+}
+
+template<class F, class V1, class... V>
+void apply(F f, V1 v1, V... v)
+{
+ apply(VariadicBind<F, int>{f, v1}, v...);
+}
+
+void func(int, int) { }
+
+int main()
+{
+ apply(func, 0, 0);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-36.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-36.C
index 2665188a630..0a28354f5dd 100644
--- a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-36.C
+++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-36.C
@@ -2,20 +2,22 @@
// { dg-options "-std=c++11 -pedantic" }
// { dg-do compile { target { { i?86-*-* x86_64-*-* } && ia32 } } }
+// c++11 attributes that apply to types are ignored for now
+
class T;
class L { };
class P : public L
{
- typedef void (T::* [[gnu::__stdcall__]] F2) (L*); // { dg-warning "only applies to function types" }
- typedef void (T::*F) (L*) [[gnu::__stdcall__]];
+ typedef void (T::* [[gnu::__stdcall__]] F2) (L*); // { dg-warning "ignored" }
+ typedef void (T::*F) (L*) [[gnu::__stdcall__]]; // { dg-warning "ignored" }
void f(bool aAdd);
};
class T
{
public:
- virtual void A(L *listener) [[gnu::__stdcall__]] = 0;
- virtual void R(L *listener) [[gnu::__stdcall__]] = 0;
+ virtual void A(L *listener) [[gnu::__stdcall__]] = 0; // { dg-warning "ignored" }
+ virtual void R(L *listener) [[gnu::__stdcall__]] = 0; // { dg-warning "ignored" }
};
void P::f(bool aAdd)
{
diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-37.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-37.C
index 15d69e8175e..9b769428071 100644
--- a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-37.C
+++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-37.C
@@ -2,12 +2,14 @@
// { dg-options "-std=c++11 -pedantic" }
// { dg-do compile { target { { i?86-*-* x86_64-*-* } && ia32 } } }
+// c++11 attributes that apply to types are ignored for now
+
struct S {
int x;
S(const S &s) {}
};
-S getS() [[gnu::__stdcall__]];
+S getS() [[gnu::__stdcall__]]; // { dg-warning "ignored" }
void test()
{
diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-8.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-8.C
index a842b5352cc..aa1491aed53 100644
--- a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-8.C
+++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-8.C
@@ -2,5 +2,5 @@
// { dg-do compile { target { { i?86-*-* x86_64-*-* } && ia32 } } }
extern int * ([[gnu::stdcall]] *fooPtr)( void); // { dg-error "expected" }
-int * [[gnu::stdcall]] myFn01( void) { return 0; }// { dg-warning "attribute only applies to function types" }
+int * [[gnu::stdcall]] myFn01( void) { return 0; }// { dg-warning "ignored" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor1.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor1.C
new file mode 100644
index 00000000000..99603106512
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor1.C
@@ -0,0 +1,17 @@
+// { dg-options -std=c++11 }
+
+struct A
+{
+ int i;
+ constexpr A(int i): i(i) {}
+};
+
+struct B: A
+{
+ using A::A;
+};
+
+constexpr B b(42);
+
+#define SA(X) static_assert((X),#X)
+SA(b.i == 42);
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor10.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor10.C
new file mode 100644
index 00000000000..de5745358ef
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor10.C
@@ -0,0 +1,14 @@
+// { dg-options "-std=c++11" }
+
+struct A
+{
+ template <class... Ts> A(Ts...);
+};
+
+struct B: A
+{
+ using A::A;
+};
+
+B b1(42);
+B b2(1.0, 42, (void*)0);
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor11.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor11.C
new file mode 100644
index 00000000000..8e8ff010ffe
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor11.C
@@ -0,0 +1,14 @@
+// { dg-options "-std=c++11" }
+
+struct A
+{
+ A(int, ...);
+};
+
+struct B: A
+{
+ using A::A;
+};
+
+B b1(42);
+B b2(42, 1.0); // { dg-error "no match" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor12.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor12.C
new file mode 100644
index 00000000000..257487efb11
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor12.C
@@ -0,0 +1,26 @@
+// { dg-options "-std=c++11" }
+// { dg-do run }
+
+struct A
+{
+ int i;
+ template <class T>
+ A(T t) noexcept : i(t) {}
+};
+
+struct C
+{
+ C() { throw 42; }
+};
+
+struct B: A, C
+{
+ using A::A;
+};
+
+int main()
+{
+ try { B b(24); }
+ catch (int) { return 0; }
+ __builtin_abort();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor13.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor13.C
new file mode 100644
index 00000000000..2e18e5d62f3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor13.C
@@ -0,0 +1,22 @@
+// { dg-options "-std=c++11" }
+
+struct A
+{
+ int i;
+ template <class T> A(T t);
+};
+
+struct C
+{
+ C() = delete; // { dg-error "declared here" }
+};
+
+struct B: A, C
+{
+ using A::A; // { dg-error "C::C" }
+};
+
+int main()
+{
+ B b(24); // { dg-error "B::B" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor2.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor2.C
new file mode 100644
index 00000000000..621ba604c22
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor2.C
@@ -0,0 +1,19 @@
+// { dg-options -std=c++11 }
+
+struct A
+{
+ int i;
+ constexpr A(int, int i = num): i(i) {}
+private:
+ static const int num = 42;
+};
+
+struct B: A
+{
+ using A::A;
+};
+
+constexpr B b(24);
+
+#define SA(X) static_assert((X),#X)
+SA(b.i == 42);
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor3.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor3.C
new file mode 100644
index 00000000000..7116e2f0700
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor3.C
@@ -0,0 +1,17 @@
+// { dg-options -std=c++11 }
+
+struct B1 {
+ B1(int);
+};
+struct B2 {
+ B2(int);
+};
+struct D1 : B1, B2 {
+ using B1::B1; // { dg-error "inherited" }
+ using B2::B2; // { dg-error "inherited" }
+}; // ill-formed: attempts to declare D1(int) twice
+struct D2 : B1, B2 {
+ using B1::B1;
+ using B2::B2;
+ D2(int); // OK: user declaration supersedes both implicit declarations
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor4.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor4.C
new file mode 100644
index 00000000000..b6754dc4a46
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor4.C
@@ -0,0 +1,18 @@
+// From N3337
+// { dg-options -std=c++11 }
+
+struct B1 {
+ B1(int);
+};
+struct B2 {
+ B2(int = 13, int = 42);
+};
+struct D1 : B1 {
+ using B1::B1;
+};
+struct D2 : B2 {
+ using B2::B2;
+};
+
+D1 d1(1);
+D2 d2a(2), d2b(3,4);
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor5.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor5.C
new file mode 100644
index 00000000000..a8aa6d98ad9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor5.C
@@ -0,0 +1,21 @@
+// { dg-options "-std=c++11" }
+
+struct B1 {
+ B1(int) { }
+};
+struct B2 {
+ B2(double) { }
+};
+struct D1 : B1 { // { dg-error "no match" }
+ using B1::B1; // implicitly declares D1(int)
+ int x;
+};
+void test() {
+ D1 d(6); // OK: d.x is not initialized
+ D1 e; // { dg-error "deleted" } D1 has no default constructor
+}
+struct D2 : B2 {
+ using B2::B2; // { dg-error "no match" } implicitly declares D2(double)
+ B1 b;
+};
+D2 f(1.0); // { dg-error "deleted" } B1 has no default constructor
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor6.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor6.C
new file mode 100644
index 00000000000..5ac88d6b7db
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor6.C
@@ -0,0 +1,15 @@
+// { dg-options "-std=c++11" }
+
+extern "C" int printf (const char *, ...);
+template< class T >
+struct D : T {
+ using T::T;
+ // declares all constructors from class T
+ ~D() { printf ("Destroying wrapper\n"); }
+};
+
+struct A {
+ A(int);
+};
+
+D<A> d(42);
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor7.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor7.C
new file mode 100644
index 00000000000..22608246706
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor7.C
@@ -0,0 +1,18 @@
+// { dg-options "-std=c++11" }
+
+struct A
+{
+ int i;
+ template <class T>
+ constexpr A(T t): i(t) {}
+};
+
+struct B: A
+{
+ using A::A;
+};
+
+constexpr B b(42);
+
+#define SA(X) static_assert((X),#X)
+SA(b.i == 42);
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor8.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor8.C
new file mode 100644
index 00000000000..d55d3d2a5bf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor8.C
@@ -0,0 +1,20 @@
+// { dg-options "-std=c++11" }
+
+struct A
+{
+ int i;
+ explicit A(int i): i(i) {}
+};
+
+struct B: A
+{
+ using A::A;
+};
+
+void f(B);
+
+int main()
+{
+ f(B(42)); // OK
+ f(42); // { dg-error "could not convert" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor9.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor9.C
new file mode 100644
index 00000000000..dc5e86b6348
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor9.C
@@ -0,0 +1,15 @@
+// { dg-options "-std=c++11" }
+
+class A
+{
+ int i;
+protected:
+ A(int i): i(i) {}
+};
+
+struct B: A
+{
+ using A::A; // { dg-error "protected" }
+};
+
+B b(42); // { dg-error "this context" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist67.C b/gcc/testsuite/g++.dg/cpp0x/initlist67.C
new file mode 100644
index 00000000000..491d4cf0636
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist67.C
@@ -0,0 +1,27 @@
+// PR c++/50478
+// { dg-do compile { target c++11 } }
+
+#include <initializer_list>
+
+namespace std
+{
+ template<typename _Key>
+ struct set
+ {
+ void insert(const _Key&);
+ void insert(initializer_list<_Key>);
+ };
+
+ struct string
+ {
+ string(const string&, __SIZE_TYPE__, __SIZE_TYPE__ = -1);
+ string(const char*);
+ string(initializer_list<char>);
+ };
+}
+
+int main()
+{
+ std::set<std::string> s;
+ s.insert( { "abc", "def", "hij"} );
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice9.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice9.C
new file mode 100644
index 00000000000..0a88bc8752b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice9.C
@@ -0,0 +1,18 @@
+// PR c++/53741
+// { dg-do compile { target c++11 } }
+
+struct X
+{
+ template <class T> static void bar() {}
+
+ template <class T> void foo(T p)
+ {
+ [&] { bar<T>(); };
+ }
+};
+
+int main()
+{
+ X x;
+ x.foo(3);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr52744.C b/gcc/testsuite/g++.dg/cpp0x/pr52744.C
new file mode 100644
index 00000000000..1a01fb2957f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr52744.C
@@ -0,0 +1,83 @@
+// PR c++/52744
+// { dg-do compile { target c++11 } }
+
+struct T
+{
+ int a;
+ void b(){}
+ int c(int)
+ {
+ return 1;
+ }
+};
+
+template<typename CT, CT> struct member_helper;
+
+template<typename FT, FT(T::*mem)>
+struct member_helper<FT(T::*), mem>
+{
+ static const char* worker()
+ {
+ return "for members";
+ }
+};
+
+template<typename Return, typename... Args, Return(T::*fun)(Args...)>
+struct member_helper<Return(T::*)(Args...), fun>
+{
+ static const char* worker()
+ {
+ return "for member functions returning non void";
+ }
+};
+
+template<typename... Args, void(T::*fun)(Args...)>
+struct member_helper<void(T::*)(Args...), fun>
+{
+ static const char* worker()
+ {
+ return "for member functions returning void";
+ }
+};
+
+void member_test()
+{
+ member_helper<decltype(&T::a), &T::a>::worker();
+ member_helper<decltype(&T::b), &T::b>::worker();
+ member_helper<decltype(&T::c), &T::c>::worker();
+}
+
+typedef void lua_State;
+
+template<typename T, T> class function_helper
+{
+ static_assert(sizeof(T) != sizeof(T),
+ "Error: function_helper works with functions (duh)");
+};
+
+template<typename Return, typename... Args, Return(*func)(Args...)>
+struct function_helper<Return(*)(Args...), func>
+{
+ static int wrapper(lua_State* l)
+ {
+ return 1;
+ }
+};
+
+template<typename... Args, void(*func)(Args...)>
+struct function_helper<void(*)(Args...), func>
+{
+ static int wrapper(lua_State* l)
+ {
+ return 0;
+ }
+};
+
+int ciao(int){ return 0; }
+void ciao2(int){}
+
+void function_test()
+{
+ function_helper<decltype(&ciao), &ciao>::wrapper(0);
+ function_helper<decltype(&ciao2), &ciao2>::wrapper(0);
+}
diff --git a/gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C b/gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C
index b8133909a7f..c13161d3ceb 100644
--- a/gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C
+++ b/gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C
@@ -1,7 +1,7 @@
/* Test that #pragma GCC visibility does not override class member specific settings. */
/* { dg-do compile } */
/* { dg-require-visibility "internal" } */
-/* { dg-final { scan-assembler "\\.internal.*Foo.methodEv" { target { ! *-*-solaris2* } { ! *-*-darwin* } } } }*/
+/* { dg-final { scan-assembler "\\.internal.*Foo.methodEv" { target { ! { *-*-solaris2* *-*-darwin* } } } } } */
/* { dg-final { scan-assembler "\\.(internal|hidden).*Foo.methodEv" { target *-*-solaris2* } } } */
#pragma GCC visibility push(hidden)
diff --git a/gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C b/gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C
index 3ceaf4a2523..25e9ceac076 100644
--- a/gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C
+++ b/gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C
@@ -1,7 +1,7 @@
/* Test that #pragma GCC visibility does not override class member specific settings. */
/* { dg-do compile } */
/* { dg-require-visibility "internal" } */
-/* { dg-final { scan-assembler "\\.internal.*Foo.methodEv" { target { ! *-*-solaris2* } { ! *-*-darwin* } } } } */
+/* { dg-final { scan-assembler "\\.internal.*Foo.methodEv" { target { ! { *-*-solaris2* *-*-darwin* } } } } } */
/* { dg-final { scan-assembler "\\.(internal|hidden).*Foo.methodEv" { target *-*-solaris2* } } } */
#pragma GCC visibility push(hidden)
diff --git a/gcc/testsuite/g++.dg/ext/weak5.C b/gcc/testsuite/g++.dg/ext/weak5.C
new file mode 100644
index 00000000000..f2924a0b6d8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/weak5.C
@@ -0,0 +1,12 @@
+// PR c++/36107
+// { dg-do assemble }
+// { dg-require-weak "" }
+
+class Test {
+ public:
+ Test() __attribute__((weak));
+};
+
+void test() {
+ Test test;
+}
diff --git a/gcc/testsuite/g++.dg/gomp/tls-5.C b/gcc/testsuite/g++.dg/gomp/tls-5.C
index 74e4faaa884..f1dcdae688d 100644
--- a/gcc/testsuite/g++.dg/gomp/tls-5.C
+++ b/gcc/testsuite/g++.dg/gomp/tls-5.C
@@ -1,6 +1,7 @@
// The reference temp should be TLS, not normal data.
// { dg-require-effective-target c++11 }
-// { dg-final { scan-assembler-not "\\.data" } }
+// { dg-require-alias }
+// { dg-final { scan-assembler-not "\\.data" { target tls_native } } }
extern int&& ir;
#pragma omp threadprivate (ir)
diff --git a/gcc/testsuite/g++.dg/init/bitfield3.C b/gcc/testsuite/g++.dg/init/bitfield3.C
new file mode 100644
index 00000000000..23db2d4a34c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/bitfield3.C
@@ -0,0 +1,11 @@
+// PR c++/43663
+
+struct S
+{
+ S(): i(0) {}
+ int i : 3;
+};
+
+S s;
+
+const int& cr(s.i);
diff --git a/gcc/testsuite/g++.dg/opt/pr52643.C b/gcc/testsuite/g++.dg/opt/pr52643.C
new file mode 100644
index 00000000000..271dd76c12d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr52643.C
@@ -0,0 +1,64 @@
+// PR c++/52643
+// { dg-options "-O" }
+
+template<class T> class already_AddRefd {};
+
+template<class T>
+class ObjRef
+{
+public:
+ ObjRef() {}
+
+ ObjRef(const already_AddRefd<T> aar) {}
+
+ ~ObjRef()
+ {
+ T* mPtr;
+ mPtr->release_ref();
+ }
+
+ operator T* () const
+ {
+ return __null;
+ }
+
+ template<class U>
+ void operator= (const already_AddRefd<U>& newAssign) {}
+};
+
+class MyRetClass {
+public:
+ void release_ref();
+};
+
+class MyClass
+{
+ void appendChild();
+ void getTripleOutOfByPredicate();
+ already_AddRefd<MyRetClass> getNextTriple();
+};
+
+void
+MyClass::getTripleOutOfByPredicate()
+{
+ ObjRef<MyRetClass> t (getNextTriple());
+
+ if (t == __null)
+ throw MyRetClass();
+}
+
+void
+MyClass::appendChild()
+{
+ while (1)
+ {
+ try
+ {
+ ObjRef<MyRetClass> t (getNextTriple());
+ continue;
+ }
+ catch (MyRetClass)
+ {
+ }
+ }
+}
diff --git a/gcc/testsuite/g++.dg/parse/friend-main.C b/gcc/testsuite/g++.dg/parse/friend-main.C
new file mode 100644
index 00000000000..e6d32e71ba4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/friend-main.C
@@ -0,0 +1,30 @@
+// PR c++/24449
+
+class Fooa
+{
+ friend int main();
+};
+
+template <class T> class Foob
+{
+ friend int main();
+ int i;
+};
+
+int main()
+{
+ Foob<void> a;
+ a.i = 7;
+}
+
+class Fooc
+{
+ template<class T> friend int main(); // { dg-error "cannot declare .::main. to be a template" }
+};
+
+template<class T> class Food
+{
+ template<class U> friend int main(); // { dg-error "cannot declare .::main. to be a template" }
+};
+
+template<class U> int main() {} // { dg-error "cannot declare .::main. to be a template" }
diff --git a/gcc/testsuite/g++.dg/parse/pr43765.C b/gcc/testsuite/g++.dg/parse/pr43765.C
new file mode 100644
index 00000000000..0b341ddb8ab
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/pr43765.C
@@ -0,0 +1,14 @@
+// PR c++/43765
+// { dg-options "" }
+
+struct SomeType
+{
+ const char *values[];
+};
+const char *temp[] = {"607", "612", 0};
+
+SomeType vals[] =
+ {
+ { values : temp, },
+ 0
+ }; // { dg-error "invalid" }
diff --git a/gcc/testsuite/g++.dg/parse/tmpl-outside1.C b/gcc/testsuite/g++.dg/parse/tmpl-outside1.C
index e63e3cd4412..0713f170aa0 100644
--- a/gcc/testsuite/g++.dg/parse/tmpl-outside1.C
+++ b/gcc/testsuite/g++.dg/parse/tmpl-outside1.C
@@ -7,4 +7,4 @@ struct X
template <int i> struct Y {};
};
-typedef X::template Y<0> y; // { dg-error "template|invalid" }
+typedef X::template Y<0> y;
diff --git a/gcc/testsuite/g++.dg/parse/tmpl-outside2.C b/gcc/testsuite/g++.dg/parse/tmpl-outside2.C
new file mode 100644
index 00000000000..d35656f609e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/tmpl-outside2.C
@@ -0,0 +1,19 @@
+// PR c++/50080
+
+template <typename T>
+struct A
+{
+ template <typename U>
+ struct B {};
+};
+
+template <typename T>
+void test()
+{
+ typename A<T>::template B<int> b;
+}
+
+int main()
+{
+ typename A<double>::template B<int> b;
+}
diff --git a/gcc/testsuite/g++.dg/pr53055.C b/gcc/testsuite/g++.dg/pr53055.C
new file mode 100644
index 00000000000..787af9d156f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr53055.C
@@ -0,0 +1,5 @@
+// PR c++/53055
+// { dg-do compile }
+
+struct A A :: * p ;
+int i = p ->* p ; // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/template/crash113.C b/gcc/testsuite/g++.dg/template/crash113.C
new file mode 100644
index 00000000000..3d3a562bdcd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/crash113.C
@@ -0,0 +1,50 @@
+// PR c++/53581
+
+template<class A, int M, int N>
+class Child;
+
+template<class A, int M, int N>
+class Base
+{
+public:
+ Child<A, M, N> operator-(const Base<A, M, N> &m) const
+ {
+ Child<A, M, N> diff;
+ return diff;
+ }
+
+ A test() const
+ {
+ return 0;
+ }
+
+private:
+ A values[M * N];
+};
+
+template<class A, int N>
+class Ops
+{
+public:
+ virtual ~Ops() {}
+
+ bool bar() const
+ {
+ Child<A, N, N> mat;
+ return (*static_cast<const Child<A, N, N>*>(this) - mat).test();
+ }
+};
+
+
+template<class A, int N>
+class Child<A, N, N> : public Base<A, N, N>, public Ops<A, N> {};
+
+class ImageWarp
+{
+ bool bar() const
+ {
+ return foo.bar();
+ }
+
+ Child<float, 3, 3> foo;
+};
diff --git a/gcc/testsuite/g++.dg/template/qualttp18.C b/gcc/testsuite/g++.dg/template/qualttp18.C
index 31dfa6a83d0..b4d28da5980 100644
--- a/gcc/testsuite/g++.dg/template/qualttp18.C
+++ b/gcc/testsuite/g++.dg/template/qualttp18.C
@@ -14,7 +14,7 @@ template <template <class> class TT> struct X
struct C
{
- X<A::template B> x; // { dg-error "" }
+ X<A::template B> x;
};
int main()
diff --git a/gcc/testsuite/g++.dg/tls/static2.C b/gcc/testsuite/g++.dg/tls/static2.C
new file mode 100644
index 00000000000..ab688dd8dc4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/static2.C
@@ -0,0 +1,18 @@
+// { dg-final { scan-assembler-not "_ZTHN1A1iE" } }
+// { dg-final { scan-assembler-not "_ZTWN1A1iE" } }
+// { dg-require-effective-target tls }
+
+struct A
+{
+ static __thread int i;
+};
+
+int
+test ()
+{
+ if (A::i != 8)
+ return 1;
+
+ A::i = 17;
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/tls/thread_local7.C b/gcc/testsuite/g++.dg/tls/thread_local7.C
index 77a1c05e44c..f453b965768 100644
--- a/gcc/testsuite/g++.dg/tls/thread_local7.C
+++ b/gcc/testsuite/g++.dg/tls/thread_local7.C
@@ -2,7 +2,7 @@
// { dg-require-effective-target tls }
// The reference temp should be TLS, not normal data.
-// { dg-final { scan-assembler-not "\\.data" } }
+// { dg-final { scan-assembler-not "\\.data" { target tls_native } } }
void f()
{
diff --git a/gcc/testsuite/g++.dg/tls/thread_local7g.C b/gcc/testsuite/g++.dg/tls/thread_local7g.C
index 6960598173a..3479aeb31fa 100644
--- a/gcc/testsuite/g++.dg/tls/thread_local7g.C
+++ b/gcc/testsuite/g++.dg/tls/thread_local7g.C
@@ -3,7 +3,7 @@
// { dg-require-alias }
// The reference temp should be TLS, not normal data.
-// { dg-final { scan-assembler-not "\\.data" } }
+// { dg-final { scan-assembler-not "\\.data" { target tls_native } } }
thread_local int&& ir = 42;
diff --git a/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C
index c57096cc063..6cb39809d6c 100644
--- a/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C
+++ b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C
@@ -14,6 +14,7 @@ extern void *memmove (void *__restrict, const void *__restrict, size_t);
extern int memcmp (const void *, const void *, size_t);
extern char *strncpy (char *__restrict, const char *__restrict, size_t);
extern char *strncat (char *__restrict, const char *__restrict, size_t);
+extern char *stpncpy (char *__restrict, const char *__restrict, size_t);
extern char *strndup (const char *, size_t);
extern int strncmp (const char *, const char *, size_t);
extern int strncasecmp (const char *, const char *, size_t);
@@ -56,6 +57,13 @@ strncat (char *dest, const char *src, size_t len)
{
return __builtin___strncat_chk (dest, src, len, bos (dest));
}
+
+__attribute__((__always_inline__, __gnu_inline__, __artificial__))
+extern inline char *
+stpncpy (char *__restrict dest, const char *__restrict src, size_t len)
+{
+ return __builtin___stpncpy_chk (dest, src, len, bos (dest));
+}
#endif
}
@@ -127,23 +135,23 @@ f1 (void *x, int z)
memmove (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
memmove (x, pa4, sizeof (__typeof (pa4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
- z += memcmp (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pa1, x, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
-
- z += memcmp (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
- z += memcmp (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pa1, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" }
+ z += memcmp (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pa1, x, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+
+ z += memcmp (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" }
+ z += memcmp (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pa1, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
// These are correct, no warning.
memset (&a, 0, sizeof a);
@@ -331,23 +339,23 @@ f2 (void *x, int z)
memmove (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
memmove (x, pb4, sizeof (__typeof (pb4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
- z += memcmp (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pb1, x, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
-
- z += memcmp (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
- z += memcmp (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pb1, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" }
+ z += memcmp (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pb1, x, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+
+ z += memcmp (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" }
+ z += memcmp (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pb1, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
// These are correct, no warning.
memset (&b, 0, sizeof b);
@@ -519,17 +527,17 @@ f3 (void *x, char *y, int z, X w)
memmove (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
memmove (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += memcmp (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += memcmp (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += memcmp (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
- z += memcmp (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (y, x, sizeof (y)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += memcmp (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += memcmp (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += memcmp (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" }
+ z += memcmp (w, x, sizeof w); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
- z += memcmp (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += memcmp (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += memcmp (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += memcmp (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
- z += memcmp (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, y, sizeof (y)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+ z += memcmp (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+ z += memcmp (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+ z += memcmp (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" }
+ z += memcmp (x, w, sizeof w); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
// These are correct, no warning.
memset (y, 0, sizeof (*y));
@@ -673,23 +681,29 @@ f3 (void *x, char *y, int z, X w)
}
int
-f4 (char *x, char **y, int z)
+f4 (char *x, char **y, int z, char w[64])
{
const char *s1 = "foobarbaz";
const char *s2 = "abcde12345678";
strncpy (x, s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
strncat (x, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ stpncpy (x, s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
y[0] = strndup (s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += strncmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += strncmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += strncasecmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += strncasecmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ z += strncmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += strncmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+ z += strncasecmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += strncasecmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+
+ strncpy (w, s1, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ strncat (w, s2, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ stpncpy (w, s1, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
// These are correct, no warning.
const char s3[] = "foobarbaz";
const char s4[] = "abcde12345678";
strncpy (x, s3, sizeof (s3));
strncat (x, s4, sizeof (s4));
+ stpncpy (x, s3, sizeof (s3));
y[1] = strndup (s3, sizeof (s3));
z += strncmp (s3, s4, sizeof (s3));
z += strncmp (s3, s4, sizeof (s4));
diff --git a/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C
index d5a29d8f582..9e2805d2b74 100644
--- a/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C
+++ b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C
@@ -14,6 +14,7 @@ extern void *memmove (void *__restrict, const void *__restrict, size_t);
extern int memcmp (const void *, const void *, size_t);
extern char *strncpy (char *__restrict, const char *__restrict, size_t);
extern char *strncat (char *__restrict, const char *__restrict, size_t);
+extern char *stpncpy (char *__restrict, const char *__restrict, size_t);
extern char *strndup (const char *, size_t);
extern int strncmp (const char *, const char *, size_t);
extern int strncasecmp (const char *, const char *, size_t);
@@ -56,6 +57,13 @@ strncat (char *dest, const char *src, size_t len)
{
return __builtin___strncat_chk (dest, src, len, bos (dest));
}
+
+__attribute__((__always_inline__, __gnu_inline__, __artificial__))
+extern inline char *
+stpncpy (char *__restrict dest, const char *__restrict src, size_t len)
+{
+ return __builtin___stpncpy_chk (dest, src, len, bos (dest));
+}
#endif
}
@@ -128,23 +136,23 @@ f1 (void *x, int z)
memmove (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
memmove (x, pa4, sizeof (__typeof (pa4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
- z += memcmp (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pa1, x, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
-
- z += memcmp (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
- z += memcmp (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pa1, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" }
+ z += memcmp (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pa1, x, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+
+ z += memcmp (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" }
+ z += memcmp (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pa1, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
// These are correct, no warning.
memset (&a, 0, sizeof a);
@@ -333,23 +341,23 @@ f2 (void *x, int z)
memmove (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
memmove (x, pb4, sizeof (__typeof (pb4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
- z += memcmp (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
- z += memcmp (pb1, x, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
-
- z += memcmp (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
- z += memcmp (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (x, pb1, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
- z += memcmp (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" }
+ z += memcmp (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
+ z += memcmp (pb1, x, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" }
+
+ z += memcmp (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" }
+ z += memcmp (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
+ z += memcmp (x, pb1, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" }
// These are correct, no warning.
memset (&b, 0, sizeof b);
@@ -522,17 +530,17 @@ f3 (void *x, char *y, int z, X w)
memmove (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
memmove (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
- z += memcmp (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += memcmp (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += memcmp (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += memcmp (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
- z += memcmp (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (y, x, sizeof (y)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += memcmp (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += memcmp (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += memcmp (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" }
+ z += memcmp (w, x, sizeof w); // { dg-warning "call is the same expression as the first source; did you mean to dereference it" }
- z += memcmp (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += memcmp (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += memcmp (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += memcmp (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
- z += memcmp (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, y, sizeof (y)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+ z += memcmp (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+ z += memcmp (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+ z += memcmp (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" }
+ z += memcmp (x, w, sizeof w); // { dg-warning "call is the same expression as the second source; did you mean to dereference it" }
// These are correct, no warning.
memset (y, 0, sizeof (*y));
@@ -677,23 +685,29 @@ f3 (void *x, char *y, int z, X w)
template <int N>
int
-f4 (char *x, char **y, int z)
+f4 (char *x, char **y, int z, char w[64])
{
const char *s1 = "foobarbaz";
const char *s2 = "abcde12345678";
strncpy (x, s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
strncat (x, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ stpncpy (x, s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
y[0] = strndup (s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += strncmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += strncmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
- z += strncasecmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
- z += strncasecmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ z += strncmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += strncmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+ z += strncasecmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" }
+ z += strncasecmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" }
+
+ strncpy (w, s1, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ strncat (w, s2, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ stpncpy (w, s1, sizeof (w)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
// These are correct, no warning.
const char s3[] = "foobarbaz";
const char s4[] = "abcde12345678";
strncpy (x, s3, sizeof (s3));
strncat (x, s4, sizeof (s4));
+ stpncpy (x, s3, sizeof (s3));
y[1] = strndup (s3, sizeof (s3));
z += strncmp (s3, s4, sizeof (s3));
z += strncmp (s3, s4, sizeof (s4));
@@ -704,12 +718,12 @@ f4 (char *x, char **y, int z)
}
int
-f (void *x, char *y, int z, X w, char **u)
+f (void *x, char *y, int z, X w, char **u, char v[64])
{
z += f1<0> (x, z);
z += f2<0> (x, z);
z += f3<0> (x, y, z, w);
- z += f4<0> (y, u, z);
+ z += f4<0> (y, u, z, v);
return z;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memtemp87.C b/gcc/testsuite/g++.old-deja/g++.pt/memtemp87.C
index 99b4cd384fb..2554518b4b4 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/memtemp87.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/memtemp87.C
@@ -12,5 +12,4 @@ public:
template<template<class> class>
class Y {
};
-Q::template X<int> x; // { dg-error "" } template syntax
-
+Q::template X<int> x;
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/overload13.C b/gcc/testsuite/g++.old-deja/g++.pt/overload13.C
index f66f1038c7c..78a5e6d6ab8 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/overload13.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/overload13.C
@@ -7,5 +7,5 @@ struct A {
int main ()
{
A a;
- return a.template f (0); // { dg-error "" }
+ return a.template f (0);
}
diff --git a/gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c b/gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c
new file mode 100644
index 00000000000..b683be7ceff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c
@@ -0,0 +1,456 @@
+/* Test -Wsizeof-pointer-memaccess warnings. */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+typedef __SIZE_TYPE__ size_t;
+extern void bzero (void *, size_t);
+extern void bcopy (void *, const void *, size_t);
+extern int bcmp (const void *, const void *, size_t);
+
+struct A { short a, b; int c, d; long e, f; };
+typedef struct A TA;
+typedef struct A *PA;
+typedef TA *PTA;
+struct B {};
+typedef struct B TB;
+typedef struct B *PB;
+typedef TB *PTB;
+typedef int X[3][3][3];
+
+int
+f1 (void *x, int z)
+{
+ struct A a, *pa1 = &a;
+ TA *pa2 = &a;
+ PA pa3 = &a;
+ PTA pa4 = &a;
+ bzero (&a, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ bzero (pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bzero (pa2, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bzero (pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bzero (pa4, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bzero (pa1, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bzero (pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bzero (pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bzero (pa4, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ bcopy (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ bcopy (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bcopy (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bcopy (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bcopy (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bcopy (x, pa1, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (x, pa4, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ bcopy (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ bcopy (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ bcopy (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ bcopy (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ bcopy (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ bcopy (pa1, x, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (pa4, x, sizeof (__typeof (pa4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+
+ z += bcmp (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */
+ z += bcmp (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += bcmp (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += bcmp (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += bcmp (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += bcmp (pa1, x, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+ z += bcmp (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+ z += bcmp (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+
+ z += bcmp (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */
+ z += bcmp (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += bcmp (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += bcmp (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += bcmp (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += bcmp (x, pa1, sizeof (struct A *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+ z += bcmp (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+ z += bcmp (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+
+ /* These are correct, no warning. */
+ bzero (&a, sizeof a);
+ bzero (&a, sizeof (a));
+ bzero (&a, sizeof (struct A));
+ bzero (&a, sizeof (const struct A));
+ bzero (&a, sizeof (volatile struct A));
+ bzero (&a, sizeof (volatile const struct A));
+ bzero (&a, sizeof (TA));
+ bzero (&a, sizeof (__typeof (*&a)));
+ bzero (pa1, sizeof (*pa1));
+ bzero (pa2, sizeof (*pa3));
+ bzero (pa3, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ bzero ((void *) &a, sizeof (&a));
+ bzero ((char *) &a, sizeof (&a));
+ bzero (&a, sizeof (&a) + 0);
+ bzero (&a, 0 + sizeof (&a));
+
+ /* These are correct, no warning. */
+ bcopy (x, &a, sizeof a);
+ bcopy (x, &a, sizeof (a));
+ bcopy (x, &a, sizeof (struct A));
+ bcopy (x, &a, sizeof (const struct A));
+ bcopy (x, &a, sizeof (volatile struct A));
+ bcopy (x, &a, sizeof (volatile const struct A));
+ bcopy (x, &a, sizeof (TA));
+ bcopy (x, &a, sizeof (__typeof (*&a)));
+ bcopy (x, pa1, sizeof (*pa1));
+ bcopy (x, pa2, sizeof (*pa3));
+ bcopy (x, pa3, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ bcopy (x, (void *) &a, sizeof (&a));
+ bcopy (x, (char *) &a, sizeof (&a));
+ bcopy (x, &a, sizeof (&a) + 0);
+ bcopy (x, &a, 0 + sizeof (&a));
+
+ /* These are correct, no warning. */
+ bcopy (&a, x, sizeof a);
+ bcopy (&a, x, sizeof (a));
+ bcopy (&a, x, sizeof (struct A));
+ bcopy (&a, x, sizeof (const struct A));
+ bcopy (&a, x, sizeof (volatile struct A));
+ bcopy (&a, x, sizeof (volatile const struct A));
+ bcopy (&a, x, sizeof (TA));
+ bcopy (&a, x, sizeof (__typeof (*&a)));
+ bcopy (pa1, x, sizeof (*pa1));
+ bcopy (pa2, x, sizeof (*pa3));
+ bcopy (pa3, x, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ bcopy ((void *) &a, x, sizeof (&a));
+ bcopy ((char *) &a, x, sizeof (&a));
+ bcopy (&a, x, sizeof (&a) + 0);
+ bcopy (&a, x, 0 + sizeof (&a));
+
+ /* These are correct, no warning. */
+ z += bcmp (&a, x, sizeof a);
+ z += bcmp (&a, x, sizeof (a));
+ z += bcmp (&a, x, sizeof (struct A));
+ z += bcmp (&a, x, sizeof (const struct A));
+ z += bcmp (&a, x, sizeof (volatile struct A));
+ z += bcmp (&a, x, sizeof (volatile const struct A));
+ z += bcmp (&a, x, sizeof (TA));
+ z += bcmp (&a, x, sizeof (__typeof (*&a)));
+ z += bcmp (pa1, x, sizeof (*pa1));
+ z += bcmp (pa2, x, sizeof (*pa3));
+ z += bcmp (pa3, x, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ z += bcmp ((void *) &a, x, sizeof (&a));
+ z += bcmp ((char *) &a, x, sizeof (&a));
+ z += bcmp (&a, x, sizeof (&a) + 0);
+ z += bcmp (&a, x, 0 + sizeof (&a));
+
+ /* These are correct, no warning. */
+ z += bcmp (x, &a, sizeof a);
+ z += bcmp (x, &a, sizeof (a));
+ z += bcmp (x, &a, sizeof (struct A));
+ z += bcmp (x, &a, sizeof (const struct A));
+ z += bcmp (x, &a, sizeof (volatile struct A));
+ z += bcmp (x, &a, sizeof (volatile const struct A));
+ z += bcmp (x, &a, sizeof (TA));
+ z += bcmp (x, &a, sizeof (__typeof (*&a)));
+ z += bcmp (x, pa1, sizeof (*pa1));
+ z += bcmp (x, pa2, sizeof (*pa3));
+ z += bcmp (x, pa3, sizeof (__typeof (*pa3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ z += bcmp (x, (void *) &a, sizeof (&a));
+ z += bcmp (x, (char *) &a, sizeof (&a));
+ z += bcmp (x, &a, sizeof (&a) + 0);
+ z += bcmp (x, &a, 0 + sizeof (&a));
+
+ return z;
+}
+
+int
+f2 (void *x, int z)
+{
+ struct B b, *pb1 = &b;
+ TB *pb2 = &b;
+ PB pb3 = &b;
+ PTB pb4 = &b;
+ bzero (&b, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ bzero (pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bzero (pb2, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bzero (pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bzero (pb4, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bzero (pb1, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bzero (pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bzero (pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bzero (pb4, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ bcopy (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ bcopy (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bcopy (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bcopy (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bcopy (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ bcopy (x, pb1, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (x, pb4, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
+
+ bcopy (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ bcopy (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ bcopy (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ bcopy (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ bcopy (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ bcopy (pb1, x, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ bcopy (pb4, x, sizeof (__typeof (pb4))); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+
+ z += bcmp (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */
+ z += bcmp (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += bcmp (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += bcmp (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += bcmp (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += bcmp (pb1, x, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+ z += bcmp (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+ z += bcmp (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+
+ z += bcmp (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */
+ z += bcmp (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += bcmp (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += bcmp (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += bcmp (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += bcmp (x, pb1, sizeof (struct B *)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+ z += bcmp (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+ z += bcmp (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+
+ /* These are correct, no warning. */
+ bzero (&b, sizeof b);
+ bzero (&b, sizeof (b));
+ bzero (&b, sizeof (struct B));
+ bzero (&b, sizeof (const struct B));
+ bzero (&b, sizeof (volatile struct B));
+ bzero (&b, sizeof (volatile const struct B));
+ bzero (&b, sizeof (TB));
+ bzero (&b, sizeof (__typeof (*&b)));
+ bzero (pb1, sizeof (*pb1));
+ bzero (pb2, sizeof (*pb3));
+ bzero (pb3, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ bzero ((void *) &b, sizeof (&b));
+ bzero ((char *) &b, sizeof (&b));
+ bzero (&b, sizeof (&b) + 0);
+ bzero (&b, 0 + sizeof (&b));
+
+ /* These are correct, no warning. */
+ bcopy (x, &b, sizeof b);
+ bcopy (x, &b, sizeof (b));
+ bcopy (x, &b, sizeof (struct B));
+ bcopy (x, &b, sizeof (const struct B));
+ bcopy (x, &b, sizeof (volatile struct B));
+ bcopy (x, &b, sizeof (volatile const struct B));
+ bcopy (x, &b, sizeof (TB));
+ bcopy (x, &b, sizeof (__typeof (*&b)));
+ bcopy (x, pb1, sizeof (*pb1));
+ bcopy (x, pb2, sizeof (*pb3));
+ bcopy (x, pb3, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ bcopy (x, (void *) &b, sizeof (&b));
+ bcopy (x, (char *) &b, sizeof (&b));
+ bcopy (x, &b, sizeof (&b) + 0);
+ bcopy (x, &b, 0 + sizeof (&b));
+
+ /* These are correct, no warning. */
+ bcopy (&b, x, sizeof b);
+ bcopy (&b, x, sizeof (b));
+ bcopy (&b, x, sizeof (struct B));
+ bcopy (&b, x, sizeof (const struct B));
+ bcopy (&b, x, sizeof (volatile struct B));
+ bcopy (&b, x, sizeof (volatile const struct B));
+ bcopy (&b, x, sizeof (TB));
+ bcopy (&b, x, sizeof (__typeof (*&b)));
+ bcopy (pb1, x, sizeof (*pb1));
+ bcopy (pb2, x, sizeof (*pb3));
+ bcopy (pb3, x, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ bcopy ((void *) &b, x, sizeof (&b));
+ bcopy ((char *) &b, x, sizeof (&b));
+ bcopy (&b, x, sizeof (&b) + 0);
+ bcopy (&b, x, 0 + sizeof (&b));
+
+ /* These are correct, no warning. */
+ z += bcmp (&b, x, sizeof b);
+ z += bcmp (&b, x, sizeof (b));
+ z += bcmp (&b, x, sizeof (struct B));
+ z += bcmp (&b, x, sizeof (const struct B));
+ z += bcmp (&b, x, sizeof (volatile struct B));
+ z += bcmp (&b, x, sizeof (volatile const struct B));
+ z += bcmp (&b, x, sizeof (TB));
+ z += bcmp (&b, x, sizeof (__typeof (*&b)));
+ z += bcmp (pb1, x, sizeof (*pb1));
+ z += bcmp (pb2, x, sizeof (*pb3));
+ z += bcmp (pb3, x, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ z += bcmp ((void *) &b, x, sizeof (&b));
+ z += bcmp ((char *) &b, x, sizeof (&b));
+ z += bcmp (&b, x, sizeof (&b) + 0);
+ z += bcmp (&b, x, 0 + sizeof (&b));
+
+ /* These are correct, no warning. */
+ z += bcmp (x, &b, sizeof b);
+ z += bcmp (x, &b, sizeof (b));
+ z += bcmp (x, &b, sizeof (struct B));
+ z += bcmp (x, &b, sizeof (const struct B));
+ z += bcmp (x, &b, sizeof (volatile struct B));
+ z += bcmp (x, &b, sizeof (volatile const struct B));
+ z += bcmp (x, &b, sizeof (TB));
+ z += bcmp (x, &b, sizeof (__typeof (*&b)));
+ z += bcmp (x, pb1, sizeof (*pb1));
+ z += bcmp (x, pb2, sizeof (*pb3));
+ z += bcmp (x, pb3, sizeof (__typeof (*pb3)));
+ /* These are probably broken, but obfuscated, no warning. */
+ z += bcmp (x, (void *) &b, sizeof (&b));
+ z += bcmp (x, (char *) &b, sizeof (&b));
+ z += bcmp (x, &b, sizeof (&b) + 0);
+ z += bcmp (x, &b, 0 + sizeof (&b));
+
+ return z;
+}
+
+int
+f3 (void *x, char *y, int z, X w)
+{
+ unsigned char *y1 = (unsigned char *) __builtin_alloca (z + 16);
+ char buf1[7];
+ signed char buf2[z + 32];
+ long buf3[17];
+ int *buf4[9];
+ signed char *y2 = buf2;
+ char c;
+ char *y3;
+ bzero (y, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ bzero (y1, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ bzero (y2, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ bzero (&c, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ bzero (w, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+
+ bcopy (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ bcopy (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ bcopy (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ bcopy (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
+ bcopy (x, w, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+
+ bcopy (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ bcopy (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ bcopy (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ bcopy (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
+ bcopy (w, x, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+
+ z += bcmp (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
+ z += bcmp (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
+ z += bcmp (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
+ z += bcmp (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */
+ z += bcmp (w, x, sizeof w); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+
+ z += bcmp (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
+ z += bcmp (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
+ z += bcmp (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
+ z += bcmp (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */
+ z += bcmp (x, w, sizeof w); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+
+ /* These are correct, no warning. */
+ bzero (y, sizeof (*y));
+ bzero (y1, sizeof (*y2));
+ bzero (buf1, sizeof buf1);
+ bzero (buf3, sizeof (buf3));
+ bzero (&buf3[0], sizeof (buf3));
+ bzero (&buf4[0], sizeof (buf4));
+ bzero (w, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ bzero ((void *) y, sizeof (y));
+ bzero ((char *) y1, sizeof (y2));
+ bzero (y, sizeof (y) + 0);
+ bzero (y1, 0 + sizeof (y2));
+ bzero ((void *) &c, sizeof (&c));
+ bzero ((signed char *) &c, sizeof (&c));
+ bzero (&c, sizeof (&c) + 0);
+ bzero (&c, 0 + sizeof (&c));
+
+ /* These are correct, no warning. */
+ bcopy (x, y, sizeof (*y));
+ bcopy (x, y1, sizeof (*y2));
+ bcopy (x, buf1, sizeof buf1);
+ bcopy (x, buf3, sizeof (buf3));
+ bcopy (x, &buf3[0], sizeof (buf3));
+ bcopy (x, &buf4[0], sizeof (buf4));
+ bcopy (y, &y3, sizeof (y3));
+ bcopy (y, (char *) &y3, sizeof (y3));
+ bcopy (x, w, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ bcopy (x, (void *) y, sizeof (y));
+ bcopy (x, (char *) y1, sizeof (y2));
+ bcopy (x, y, sizeof (y) + 0);
+ bcopy (x, y1, 0 + sizeof (y2));
+ bcopy (x, (void *) &c, sizeof (&c));
+ bcopy (x, (signed char *) &c, sizeof (&c));
+ bcopy (x, &c, sizeof (&c) + 0);
+ bcopy (x, &c, 0 + sizeof (&c));
+
+ /* These are correct, no warning. */
+ bcopy (y, x, sizeof (*y));
+ bcopy (y1, x, sizeof (*y2));
+ bcopy (buf1, x, sizeof buf1);
+ bcopy (buf3, x, sizeof (buf3));
+ bcopy (&buf3[0], x, sizeof (buf3));
+ bcopy (&buf4[0], x, sizeof (buf4));
+ bcopy (&y3, y, sizeof (y3));
+ bcopy ((char *) &y3, y, sizeof (y3));
+ bcopy (w, x, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ bcopy ((void *) y, x, sizeof (y));
+ bcopy ((char *) y1, x, sizeof (y2));
+ bcopy (y, x, sizeof (y) + 0);
+ bcopy (y1, x, 0 + sizeof (y2));
+ bcopy ((void *) &c, x, sizeof (&c));
+ bcopy ((signed char *) &c, x, sizeof (&c));
+ bcopy (&c, x, sizeof (&c) + 0);
+ bcopy (&c, x, 0 + sizeof (&c));
+
+ /* These are correct, no warning. */
+ z += bcmp (y, x, sizeof (*y));
+ z += bcmp (y1, x, sizeof (*y2));
+ z += bcmp (buf1, x, sizeof buf1);
+ z += bcmp (buf3, x, sizeof (buf3));
+ z += bcmp (&buf3[0], x, sizeof (buf3));
+ z += bcmp (&buf4[0], x, sizeof (buf4));
+ z += bcmp (&y3, y, sizeof (y3));
+ z += bcmp ((char *) &y3, y, sizeof (y3));
+ z += bcmp (w, x, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ z += bcmp ((void *) y, x, sizeof (y));
+ z += bcmp ((char *) y1, x, sizeof (y2));
+ z += bcmp (y, x, sizeof (y) + 0);
+ z += bcmp (y1, x, 0 + sizeof (y2));
+ z += bcmp ((void *) &c, x, sizeof (&c));
+ z += bcmp ((signed char *) &c, x, sizeof (&c));
+ z += bcmp (&c, x, sizeof (&c) + 0);
+ z += bcmp (&c, x, 0 + sizeof (&c));
+
+ /* These are correct, no warning. */
+ z += bcmp (x, y, sizeof (*y));
+ z += bcmp (x, y1, sizeof (*y2));
+ z += bcmp (x, buf1, sizeof buf1);
+ z += bcmp (x, buf3, sizeof (buf3));
+ z += bcmp (x, &buf3[0], sizeof (buf3));
+ z += bcmp (x, &buf4[0], sizeof (buf4));
+ z += bcmp (y, &y3, sizeof (y3));
+ z += bcmp (y, (char *) &y3, sizeof (y3));
+ z += bcmp (x, w, sizeof (X));
+ /* These are probably broken, but obfuscated, no warning. */
+ z += bcmp (x, (void *) y, sizeof (y));
+ z += bcmp (x, (char *) y1, sizeof (y2));
+ z += bcmp (x, y, sizeof (y) + 0);
+ z += bcmp (x, y1, 0 + sizeof (y2));
+ z += bcmp (x, (void *) &c, sizeof (&c));
+ z += bcmp (x, (signed char *) &c, sizeof (&c));
+ z += bcmp (x, &c, sizeof (&c) + 0);
+ z += bcmp (x, &c, 0 + sizeof (&c));
+
+ return z;
+}
diff --git a/gcc/testsuite/gcc.dg/pr44194-1.c b/gcc/testsuite/gcc.dg/pr44194-1.c
index 1772a9949d3..8c6547e87f4 100644
--- a/gcc/testsuite/gcc.dg/pr44194-1.c
+++ b/gcc/testsuite/gcc.dg/pr44194-1.c
@@ -15,5 +15,5 @@ void func() {
/* { dg-final { scan-rtl-dump "global deletions = (2|3)" "dse1" } } */
/* { dg-final { cleanup-rtl-dump "dse1" } } */
-/* { dg-final { scan-rtl-dump-not "set \\(mem" "final" } } */
+/* { dg-final { scan-rtl-dump-not "insn \[^\n\]*set \\(mem" "final" } } */
/* { dg-final { cleanup-rtl-dump "final" } } */
diff --git a/gcc/testsuite/gcc.dg/pr53060.c b/gcc/testsuite/gcc.dg/pr53060.c
index 3b2f193d9e3..db5acbdb6ea 100644
--- a/gcc/testsuite/gcc.dg/pr53060.c
+++ b/gcc/testsuite/gcc.dg/pr53060.c
@@ -22,3 +22,6 @@ int main()
if (i[0] != 3) abort();
return 0;
}
+
+/* Ignore a warning that is irrelevant to the purpose of this test. */
+/* { dg-prune-output ".*GCC vector returned by reference.*" } */
diff --git a/gcc/testsuite/gcc.dg/pr54782.c b/gcc/testsuite/gcc.dg/pr54782.c
index 2a30754493e..161b043c61b 100644
--- a/gcc/testsuite/gcc.dg/pr54782.c
+++ b/gcc/testsuite/gcc.dg/pr54782.c
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-require-effective-target pthread } */
/* { dg-options "-O -ffast-math -ftree-parallelize-loops=2 -g" } */
struct S
diff --git a/gcc/testsuite/gcc.dg/pr54919.c b/gcc/testsuite/gcc.dg/pr54919.c
new file mode 100644
index 00000000000..9f1affce234
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr54919.c
@@ -0,0 +1,27 @@
+/* PR tree-optimization/54919 */
+/* Testcase by Zdenek Sojka <zsojka@seznam.cz> */
+
+/* { dg-do run } */
+/* { dg-options "-O3 -ffast-math -funroll-loops -fvariable-expansion-in-unroller" } */
+
+int a[10];
+extern void abort(void) __attribute__((noreturn));
+
+int __attribute__((__noinline__, __noclone__))
+foo (void)
+{
+ double d;
+ int i;
+ for (i = 0, d = 0; i < 64; i++)
+ d--;
+ return (int) d;
+}
+
+int
+main (void)
+{
+ if (foo () != -64)
+ abort ();
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c b/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c
index 3897518de63..8d01bc616a7 100644
--- a/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c
+++ b/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c
@@ -12,6 +12,7 @@ extern void *memmove (void *__restrict, const void *__restrict, size_t);
extern int memcmp (const void *, const void *, size_t);
extern char *strncpy (char *__restrict, const char *__restrict, size_t);
extern char *strncat (char *__restrict, const char *__restrict, size_t);
+extern char *stpncpy (char *__restrict, const char *__restrict, size_t);
extern char *strndup (const char *, size_t);
extern int strncmp (const char *, const char *, size_t);
extern int strncasecmp (const char *, const char *, size_t);
@@ -54,6 +55,13 @@ strncat (char *dest, const char *src, size_t len)
{
return __builtin___strncat_chk (dest, src, len, bos (dest));
}
+
+__attribute__((__always_inline__, __gnu_inline__, __artificial__))
+extern inline char *
+stpncpy (char *__restrict dest, const char *__restrict src, size_t len)
+{
+ return __builtin___stpncpy_chk (dest, src, len, bos (dest));
+}
#endif
struct A { short a, b; int c, d; long e, f; };
@@ -123,23 +131,23 @@ f1 (void *x, int z)
memmove (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
memmove (x, pa4, sizeof (__typeof (pa4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
- z += memcmp (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
- z += memcmp (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
- z += memcmp (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
- z += memcmp (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
- z += memcmp (pa1, x, sizeof (struct A *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
-
- z += memcmp (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
- z += memcmp (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (x, pa1, sizeof (struct A *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (&a, x, sizeof (&a)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */
+ z += memcmp (pa1, x, sizeof (pa1)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += memcmp (pa2, x, sizeof pa2); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += memcmp (pa3, x, sizeof (pa3)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += memcmp (pa4, x, sizeof pa4); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += memcmp (pa1, x, sizeof (struct A *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (pa2, x, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (pa3, x, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+
+ z += memcmp (x, &a, sizeof (&a)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */
+ z += memcmp (x, pa1, sizeof (pa1)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += memcmp (x, pa2, sizeof pa2); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += memcmp (x, pa3, sizeof (pa3)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += memcmp (x, pa4, sizeof pa4); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += memcmp (x, pa1, sizeof (struct A *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (x, pa2, sizeof (PTA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (x, pa3, sizeof (PA)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
/* These are correct, no warning. */
memset (&a, 0, sizeof a);
@@ -327,23 +335,23 @@ f2 (void *x, int z)
memmove (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
memmove (x, pb4, sizeof (__typeof (pb4)));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
- z += memcmp (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
- z += memcmp (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
- z += memcmp (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
- z += memcmp (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
- z += memcmp (pb1, x, sizeof (struct B *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" } */
-
- z += memcmp (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
- z += memcmp (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (x, pb1, sizeof (struct B *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
- z += memcmp (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (&b, x, sizeof (&b)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */
+ z += memcmp (pb1, x, sizeof (pb1)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += memcmp (pb2, x, sizeof pb2); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += memcmp (pb3, x, sizeof (pb3)); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += memcmp (pb4, x, sizeof pb4); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
+ z += memcmp (pb1, x, sizeof (struct B *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (pb2, x, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (pb3, x, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the first source; expected \[^\n\r\]* or an explicit length" } */
+
+ z += memcmp (x, &b, sizeof (&b)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */
+ z += memcmp (x, pb1, sizeof (pb1)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += memcmp (x, pb2, sizeof pb2); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += memcmp (x, pb3, sizeof (pb3)); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += memcmp (x, pb4, sizeof pb4); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
+ z += memcmp (x, pb1, sizeof (struct B *));/* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (x, pb2, sizeof (PTB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
+ z += memcmp (x, pb3, sizeof (PB)); /* { dg-warning "call is the same pointer type \[^\n\r\]* as the second source; expected \[^\n\r\]* or an explicit length" } */
/* These are correct, no warning. */
memset (&b, 0, sizeof b);
@@ -515,17 +523,17 @@ f3 (void *x, char *y, int z, X w)
memmove (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
memmove (x, w, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
- z += memcmp (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
- z += memcmp (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
- z += memcmp (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
- z += memcmp (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" } */
- z += memcmp (w, x, sizeof w); /* { dg-warning "call is the same expression as the destination; did you mean to dereference it" } */
+ z += memcmp (y, x, sizeof (y)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
+ z += memcmp (y1, x, sizeof (y1)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
+ z += memcmp (y2, x, sizeof (y2)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
+ z += memcmp (&c, x, sizeof (&c)); /* { dg-warning "call is the same expression as the first source; did you mean to remove the addressof" } */
+ z += memcmp (w, x, sizeof w); /* { dg-warning "call is the same expression as the first source; did you mean to dereference it" } */
- z += memcmp (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
- z += memcmp (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
- z += memcmp (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
- z += memcmp (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
- z += memcmp (x, w, sizeof w); /* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
+ z += memcmp (x, y, sizeof (y)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
+ z += memcmp (x, y1, sizeof (y1)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
+ z += memcmp (x, y2, sizeof (y2)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
+ z += memcmp (x, &c, sizeof (&c)); /* { dg-warning "call is the same expression as the second source; did you mean to remove the addressof" } */
+ z += memcmp (x, w, sizeof w); /* { dg-warning "call is the same expression as the second source; did you mean to dereference it" } */
/* These are correct, no warning. */
memset (y, 0, sizeof (*y));
@@ -669,23 +677,29 @@ f3 (void *x, char *y, int z, X w)
}
int
-f4 (char *x, char **y, int z)
+f4 (char *x, char **y, int z, char w[64])
{
const char *s1 = "foobarbaz";
const char *s2 = "abcde12345678";
strncpy (x, s1, sizeof (s1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
strncat (x, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ stpncpy (x, s1, sizeof (s1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
y[0] = strndup (s1, sizeof (s1)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
- z += strncmp (s1, s2, sizeof (s1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
- z += strncmp (s1, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
- z += strncasecmp (s1, s2, sizeof (s1)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
- z += strncasecmp (s1, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
+ z += strncmp (s1, s2, sizeof (s1)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
+ z += strncmp (s1, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
+ z += strncasecmp (s1, s2, sizeof (s1)); /* { dg-warning "call is the same expression as the first source; did you mean to provide an explicit length" } */
+ z += strncasecmp (s1, s2, sizeof (s2)); /* { dg-warning "call is the same expression as the second source; did you mean to provide an explicit length" } */
+
+ strncpy (w, s1, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ strncat (w, s2, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
+ stpncpy (w, s1, sizeof (w)); /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
/* These are correct, no warning. */
const char s3[] = "foobarbaz";
const char s4[] = "abcde12345678";
strncpy (x, s3, sizeof (s3));
strncat (x, s4, sizeof (s4));
+ stpncpy (x, s3, sizeof (s3));
y[1] = strndup (s3, sizeof (s3));
z += strncmp (s3, s4, sizeof (s3));
z += strncmp (s3, s4, sizeof (s4));
diff --git a/gcc/testsuite/gcc.dg/torture/pr54877.c b/gcc/testsuite/gcc.dg/torture/pr54877.c
new file mode 100644
index 00000000000..cee406e50d3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr54877.c
@@ -0,0 +1,23 @@
+/* PR tree-optimization/54877 */
+/* { dg-do run } */
+/* { dg-options "-ffast-math" } */
+
+extern void abort (void);
+
+int
+foo (void)
+{
+ double d;
+ int i;
+ for (i = 0, d = 0; i < 64; i++)
+ d--;
+ return (int) d;
+}
+
+int
+main ()
+{
+ if (foo () != -64)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr54894.c b/gcc/testsuite/gcc.dg/torture/pr54894.c
new file mode 100644
index 00000000000..277e371de62
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr54894.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+
+typedef unsigned long long uint64_t;
+
+#define n 4096
+double A[n][n] __attribute__((aligned(16)));
+double B[n][n] __attribute__((aligned(16)));
+double C[n][n] __attribute__((aligned(16)));
+
+#define tilesize 128
+
+typedef double adouble __attribute__((__aligned__(16)));
+
+void foo ()
+{
+ int ih, jh, kh, il, kl, jl;
+ for (ih = 0; ih < n; ih += tilesize)
+ for (jh = 0; jh < n; jh += tilesize)
+ for (kh = 0; kh < n; kh += tilesize)
+ for (il = 0; il < tilesize; ++il)
+ {
+ adouble *Ap = (adouble *)&A[ih+il][kh];
+ for (kl = 0; kl < tilesize; ++kl)
+ for (jl = 0; jl < tilesize; ++jl)
+ C[ih+il][jh+jl] += Ap[kl] * B[kh+kl][jh+jl];
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr54920.c b/gcc/testsuite/gcc.dg/torture/pr54920.c
new file mode 100644
index 00000000000..d1622f765a7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr54920.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+typedef short __v8hi __attribute__ ((__vector_size__ (16)));
+typedef long long __m128i __attribute__ ((__vector_size__ (16)));
+int a;
+__m128i b;
+
+void
+fn1 ()
+{
+ while (1)
+ b = (__m128i) (__v8hi) { a, 0, 0, 0, 0, 0 };
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr54915.c b/gcc/testsuite/gcc.dg/tree-ssa/pr54915.c
new file mode 100644
index 00000000000..1e11df19810
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr54915.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef double v2df __attribute__ ((__vector_size__ (16)));
+typedef double v4df __attribute__ ((__vector_size__ (32)));
+
+void f (v2df *ret, v4df* xp)
+{
+ v4df x = *xp;
+ v2df xx = { x[2], x[3] };
+ *ret = xx;
+}
diff --git a/gcc/testsuite/gcc.dg/unroll_5.c b/gcc/testsuite/gcc.dg/unroll_5.c
new file mode 100644
index 00000000000..48259eb8447
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/unroll_5.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-rtl-loop2_unroll -funroll-loops" } */
+void abort (void);
+int *a;
+int t()
+{
+ int i;
+ for (i=0;i<1000000;i++)
+ if (a[i])
+ return 1;
+ return 0;
+}
+int t2()
+{
+ int i;
+ for (i=0;i<3000000;i++)
+ if (a[i])
+ abort ();
+ return 0;
+}
+/* { dg-final { scan-rtl-dump-times "upper bound: 999999" 1 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-not "realistic bound: 999999" "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "upper bound: 2999999" 1 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "realistic bound: 2999999" 1 "loop2_unroll" } } */
+/* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-22.c b/gcc/testsuite/gcc.dg/vect/nodump-forwprop-22.c
index 60c344d05ee..526e70b1b88 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-22.c
+++ b/gcc/testsuite/gcc.dg/vect/nodump-forwprop-22.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-require-effective-target vect_double } */
/* { dg-require-effective-target vect_perm } */
-/* { dg-options "-O -fdump-tree-copyprop1" } */
+/* { dg-additional-options "-fdump-tree-copyprop1" } */
typedef double vec __attribute__((vector_size (2 * sizeof (double))));
void f (vec *px, vec *y, vec *z)
diff --git a/gcc/testsuite/gcc.dg/vect/pr48765.c b/gcc/testsuite/gcc.dg/vect/pr48765.c
index 469c4f423ce..50839e389c7 100644
--- a/gcc/testsuite/gcc.dg/vect/pr48765.c
+++ b/gcc/testsuite/gcc.dg/vect/pr48765.c
@@ -1,5 +1,6 @@
-/* { dg-do compile { target powerpc*-*-* } } */
-/* { dg-options "-m64 -O3 -mcpu=power6" } */
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { *-*-* } { "-mcpu=*" } { "-mcpu=power6" } } */
+/* { dg-options "-O3 -mcpu=power6" } */
enum reg_class
{
diff --git a/gcc/testsuite/gcc.dg/webizer.c b/gcc/testsuite/gcc.dg/webizer.c
new file mode 100644
index 00000000000..607bf6884d6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/webizer.c
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -funroll-loops" } */
+typedef struct rowbox {
+ int startx ;
+ int endx ;
+ int endx1 ;
+ int startx2 ;
+ int ypos ;
+ int desiredL ;
+} ROWBOX ;
+ROWBOX rowArray1[2] ;
+ROWBOX *rowArray = rowArray1;
+
+int numRows = 2;
+
+int row = 1;
+int block = 0;
+double ckt_size_factor ;
+
+__attribute__ ((noinline))
+configure2()
+{
+ block = 0 ;
+ for( row = 1 ; row <= numRows ; row++ ) {
+ block++ ;
+ if( rowArray[row].endx1 > 0 ) {
+ block++ ;
+ }
+ }
+}
+
+main()
+{
+ configure2();
+}
diff --git a/gcc/testsuite/gcc.target/arm/div64-unwinding.c b/gcc/testsuite/gcc.target/arm/div64-unwinding.c
index d10fb2bdd5b..7f112eeab9f 100644
--- a/gcc/testsuite/gcc.target/arm/div64-unwinding.c
+++ b/gcc/testsuite/gcc.target/arm/div64-unwinding.c
@@ -1,7 +1,6 @@
/* Performing a 64-bit division should not pull in the unwinder. */
-/* The test is expected to fail for GNU/Linux; see PR54723. */
-/* { dg-do run { xfail *-*-linux* } } */
+/* { dg-do run { target { ! *-*-linux* } } } */
/* { dg-options "-O0" } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/pr53397-1.c b/gcc/testsuite/gcc.target/i386/pr53397-1.c
index abb83c6c584..63650366ca2 100644
--- a/gcc/testsuite/gcc.dg/pr53397-1.c
+++ b/gcc/testsuite/gcc.target/i386/pr53397-1.c
@@ -1,7 +1,7 @@
/* Prefetching when the step is loop invariant. */
-/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-do compile } */
/* { dg-require-effective-target sse2 } */
-/* { dg-options "-O3 -fprefetch-loop-arrays -fdump-tree-aprefetch-details --param min-insn-to-prefetch-ratio=3 --param simultaneous-prefetches=10 -fdump-tree-aprefetch-details" } */
+/* { dg-options "-O3 -msse2 -fprefetch-loop-arrays -fdump-tree-aprefetch-details --param min-insn-to-prefetch-ratio=3 --param simultaneous-prefetches=10 -fdump-tree-aprefetch-details" } */
double data[16384];
diff --git a/gcc/testsuite/gcc.dg/pr53397-2.c b/gcc/testsuite/gcc.target/i386/pr53397-2.c
index 4793ae0a6e6..b34fafc525c 100644
--- a/gcc/testsuite/gcc.dg/pr53397-2.c
+++ b/gcc/testsuite/gcc.target/i386/pr53397-2.c
@@ -1,7 +1,7 @@
/* Not prefetching when the step is loop variant. */
-/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-do compile } */
/* { dg-require-effective-target sse2 } */
-/* { dg-options "-O3 -fprefetch-loop-arrays -fdump-tree-aprefetch-details --param min-insn-to-prefetch-ratio=3 --param simultaneous-prefetches=10 -fdump-tree-aprefetch-details" } */
+/* { dg-options "-O3 -msse2 -fprefetch-loop-arrays -fdump-tree-aprefetch-details --param min-insn-to-prefetch-ratio=3 --param simultaneous-prefetches=10 -fdump-tree-aprefetch-details" } */
double data[16384];
void donot_prefetch_when_non_constant_step_is_variant(int step, int n)
diff --git a/gcc/testsuite/gcc.target/mips/mips32-dsp-accinit-2.c b/gcc/testsuite/gcc.target/mips/mips32-dsp-accinit-2.c
index 8d06a8039a1..74608d943b9 100644
--- a/gcc/testsuite/gcc.target/mips/mips32-dsp-accinit-2.c
+++ b/gcc/testsuite/gcc.target/mips/mips32-dsp-accinit-2.c
@@ -5,7 +5,8 @@
/* { dg-skip-if "requires register frequencies" { *-*-* } { "-O0" "-Os" } { "" } } */
/* Check that the zero-initialization of the accumulator feeding into
- the madd is done by means of a mult instruction instead of mthi/mtlo. */
+ the madd is done by means of an mthi & mtlo pair instead of a
+ "mult $0,$0" instruction. */
NOMIPS16 long long f (int n, int *v, int m)
{
diff --git a/gcc/testsuite/gcc.target/sh/pr51244-13.c b/gcc/testsuite/gcc.target/sh/pr51244-13.c
new file mode 100644
index 00000000000..7e823dc030c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr51244-13.c
@@ -0,0 +1,85 @@
+/* This is a case extracted from CSiBE which contained the following
+ sequence:
+ shll r0
+ movt r0
+ tst r0,r0
+ bf .L11
+ where the 'tst r0,r0' before the branch can be omitted by inverting the
+ branch condition. The tested function contains two other tst insns. If
+ everything goes as expected we will be seeing only those other two tst
+ insns. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O2" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */
+/* { dg-final { scan-assembler-times "tst" 2 } } */
+
+static __inline__ int
+__test_bit (unsigned long nr, volatile void * addr)
+{
+ /* This is on purpose. */
+ int oldbit;
+ return oldbit & 1;
+}
+
+static __inline__ int
+__constant_test_bit (unsigned long nr, volatile void * addr)
+{
+ return (((volatile char *) addr)[(nr>>3)^7] & (1<<(nr&7))) != 0;
+}
+
+struct list_head
+{
+ struct list_head *next, *prev;
+};
+
+static inline void
+__list_del (struct list_head *prev, struct list_head *next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+static inline void
+list_del (struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ entry->next = 0;
+ entry->prev = 0;
+}
+
+extern int nr_active_pages;
+extern int nr_inactive_pages;
+extern struct list_head active_list;
+
+typedef struct page
+{
+ unsigned long flags;
+ struct list_head lru;
+} mem_map_t;
+
+void
+activate_page_nolock (struct page * page)
+{
+ if ((__builtin_constant_p((6))
+ ? __constant_test_bit((6),(&(page)->flags))
+ : __test_bit((6),(&(page)->flags)) )
+ && !(__builtin_constant_p((7))
+ ? __constant_test_bit((7),(&(page)->flags))
+ : __test_bit((7),(&(page)->flags)) ))
+ {
+ list_del(&(page)->lru);
+ nr_inactive_pages--;
+ if (!(__builtin_constant_p(6) ? __constant_test_bit((6),(&(page)->flags))
+ : __test_bit((6),(&(page)->flags))))
+ printk("", "", 43);
+
+ if ((__builtin_constant_p(7) ? __constant_test_bit((7),(&(page)->flags))
+ : __test_bit((7),(&(page)->flags))))
+ printk("", "", 43);
+
+ (__builtin_constant_p(7) ? __constant_set_bit((7),(&(page)->flags))
+ : __set_bit((7),(&(page)->flags)) );
+ list_add(&(page)->lru, &active_list);
+ nr_active_pages++;
+ }
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr51244-14.c b/gcc/testsuite/gcc.target/sh/pr51244-14.c
new file mode 100644
index 00000000000..0ff7008fbc9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr51244-14.c
@@ -0,0 +1,107 @@
+/* This is a case extracted from CSiBE which would sometimes contain the
+ following sequence:
+ cmp/eq r12,r13
+ movt r0
+ xor #1,r0
+ extu.b r0,r0
+ movt r3
+ tst r0,r0
+ bf/s .L35
+ where the negated T bit store did not combine properly. Since there are
+ other movt insns we only check for the xor and the extu. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O2" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */
+/* { dg-final { scan-assembler-not "xor|extu" } } */
+
+typedef struct transaction_s transaction_t;
+
+struct journal_head
+{
+ transaction_t * b_transaction;
+ struct journal_head *b_cpnext, *b_cpprev;
+};
+
+struct transaction_s
+{
+ struct journal_head * t_checkpoint_list;
+ transaction_t *t_cpnext, *t_cpprev;
+};
+
+struct journal_s
+{
+ transaction_t * j_checkpoint_transactions;
+ unsigned long j_first, j_last;
+};
+
+typedef struct journal_s journal_t;
+
+extern int __try_to_free_cp_buf (struct journal_head *jh);
+extern int __cleanup_transaction (journal_t *journal, transaction_t *transaction);
+extern void __flush_batch (void **bhs, int *batch_count);
+extern void* jh2bh (void*);
+
+static int
+__flush_buffer (journal_t *journal, struct journal_head *jh,
+ void **bhs, int *batch_count, int *drop_count)
+{
+ void *bh = jh2bh (jh);
+ int ret = 0;
+ if (bh)
+ {
+ bhs[*batch_count] = bh;
+ (*batch_count)++;
+ if (*batch_count == 64)
+ ret = 1;
+ }
+ else
+ {
+ int last_buffer = 0;
+ if (jh->b_cpnext == jh)
+ last_buffer = 1;
+ if (__try_to_free_cp_buf (jh))
+ {
+ (*drop_count)++;
+ ret = last_buffer;
+ }
+ }
+ return ret;
+}
+
+int
+log_do_checkpoint (journal_t *journal, int nblocks)
+{
+ transaction_t *transaction, *last_transaction, *next_transaction;
+ int batch_count = 0;
+ void *bhs[64];
+
+repeat:
+ transaction = journal->j_checkpoint_transactions;
+ if (transaction == ((void *)0))
+ return 0;
+ last_transaction = transaction->t_cpprev;
+ next_transaction = transaction;
+ do
+ {
+ struct journal_head *jh, *last_jh, *next_jh;
+ int drop_count = 0;
+ int cleanup_ret, retry = 0;
+ transaction = next_transaction;
+ next_transaction = transaction->t_cpnext;
+ jh = transaction->t_checkpoint_list;
+ last_jh = jh->b_cpprev;
+ next_jh = jh;
+ do
+ {
+ jh = next_jh;
+ next_jh = jh->b_cpnext;
+ retry = __flush_buffer(journal, jh, bhs, &batch_count, &drop_count);
+ } while (jh != last_jh && !retry);
+
+ if (retry)
+ goto repeat;
+
+ cleanup_ret = __cleanup_transaction(journal, transaction);
+ goto repeat;
+ } while (transaction != last_transaction);
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr51244-15.c b/gcc/testsuite/gcc.target/sh/pr51244-15.c
new file mode 100644
index 00000000000..ec98d5e6138
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr51244-15.c
@@ -0,0 +1,71 @@
+/* Check that the redundant test removal code in the *cbranch_t split works
+ as expected on non-SH2A targets. Because on SH2A the movrt instruction
+ is used, this test is re-used and checked differently in pr51244-16.c. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O2" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" "-m2a*" } { "" } } */
+/* { dg-final { scan-assembler-times "tst" 6 } } */
+/* { dg-final { scan-assembler-times "movt" 6 } } */
+/* { dg-final { scan-assembler-times "xor" 3 } } */
+/* { dg-final { scan-assembler-not "extu|exts|negc" } } */
+
+typedef char bool;
+
+int
+test_0 (int a, int b, int c, int* d)
+{
+ /* non SH2A: 1x tst, 1x movt, 1x xor
+ SH2A: 1x tst, 1x movrt */
+ bool x = a == 0;
+ d[2] = !x;
+ return x ? b : c;
+}
+
+int
+test_1 (int a, int b, int c, int* d)
+{
+ /* 1x tst, 1x movt */
+ bool x = a != 0;
+ d[2] = !x;
+ return x ? b : c;
+}
+
+int
+test_2 (int a, int b, int c, char* d)
+{
+ /* Check that there is no sign/zero-extension before the store.
+ non SH2A: 1x tst, 1x movt, 1x xor
+ SH2A: 1x tst, 1x movrt */
+ bool x = a == 0;
+ d[2] = !x;
+ return x ? b : c;
+}
+
+int
+test_3 (int a, int b, int c, char* d)
+{
+ /* Check that there is no sign/zero-extension before the store.
+ 1x tst, 1x movt */
+ bool x = a != 0;
+ d[2] = !x;
+ return x ? b : c;
+}
+
+int
+test_4 (int a, int b, int c, char* d)
+{
+ /* 1x tst, 1x movt */
+ bool x = a != 0;
+ d[2] = !x;
+ return !x ? b : c;
+}
+
+int
+test_5 (int a, int b, int c, char* d)
+{
+ /* non SH2A: 1x tst, 1x movt, 1x xor
+ SH2A: 1x tst, 1x movrt */
+ bool x = a == 0;
+ d[2] = !x;
+ return !x ? b : c;
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr51244-16.c b/gcc/testsuite/gcc.target/sh/pr51244-16.c
new file mode 100644
index 00000000000..8717df7f34a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr51244-16.c
@@ -0,0 +1,11 @@
+/* Check that the redundant test removal code in the *cbranch_t split works
+ as expected on SH2A targets. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O2" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m2a*" } } */
+/* { dg-final { scan-assembler-times "tst" 6 } } */
+/* { dg-final { scan-assembler-times "movt" 3 } } */
+/* { dg-final { scan-assembler-times "movrt" 3 } } */
+/* { dg-final { scan-assembler-not "extu|exts|negc" } } */
+
+#include "pr51244-15.c"
diff --git a/gcc/testsuite/gcc.target/sh/pr54602-1.c b/gcc/testsuite/gcc.target/sh/pr54602-1.c
new file mode 100644
index 00000000000..e5c035708e4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr54602-1.c
@@ -0,0 +1,15 @@
+/* Verify that the delay slot is stuffed with register pop insns for normal
+ (i.e. not interrupt handler) function returns. If everything goes as
+ expected we won't see any nop insns. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
+/* { dg-final { scan-assembler-not "nop" } } */
+
+int test00 (int a, int b);
+
+int
+test01 (int a, int b, int c, int d)
+{
+ return test00 (a, b) + c;
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr54602-2.c b/gcc/testsuite/gcc.target/sh/pr54602-2.c
new file mode 100644
index 00000000000..4f3877c41b1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr54602-2.c
@@ -0,0 +1,15 @@
+/* Verify that the delay slot is not stuffed with register pop insns for
+ interrupt handler function returns on SH1* and SH2* targets, where the
+ rte insn uses the stack pointer. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m1*" "-m2*" } } */
+/* { dg-final { scan-assembler-times "nop" 1 } } */
+
+int test00 (int a, int b);
+
+int __attribute__ ((interrupt_handler))
+test01 (int a, int b, int c, int d)
+{
+ return test00 (a, b) + c;
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr54602-3.c b/gcc/testsuite/gcc.target/sh/pr54602-3.c
new file mode 100644
index 00000000000..29292589c62
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr54602-3.c
@@ -0,0 +1,12 @@
+/* Verify that the rte delay slot is not stuffed with register pop insns
+ which touch the banked registers r0..r7 on SH3* and SH4* targets. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m3*" "-m4*" } } */
+/* { dg-final { scan-assembler-times "nop" 1 } } */
+
+int __attribute__ ((interrupt_handler))
+test00 (int a, int b, int c, int d)
+{
+ return a + b;
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr54602-4.c b/gcc/testsuite/gcc.target/sh/pr54602-4.c
new file mode 100644
index 00000000000..0b77d0983ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr54602-4.c
@@ -0,0 +1,15 @@
+/* Verify that the delay slot is stuffed with register pop insns on SH3* and
+ SH4* targets, where the stack pointer is not used by the rte insn. If
+ everything works out, we won't see a nop insn. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "*" } { "-m3*" "-m4*" } } */
+/* { dg-final { scan-assembler-not "nop" } } */
+
+int test00 (int a, int b);
+
+int __attribute__ ((interrupt_handler))
+test01 (int a, int b, int c, int d)
+{
+ return test00 (a, b) + c;
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr54680.c b/gcc/testsuite/gcc.target/sh/pr54680.c
new file mode 100644
index 00000000000..27c44d3ca4d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr54680.c
@@ -0,0 +1,66 @@
+/* Verify that the fsca input value is not converted to float and then back
+ to int. Notice that we can't count just "lds" insns because mode switches
+ use "lds.l". */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O2 -mfsca -funsafe-math-optimizations" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2*" "-m3*" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */
+/* { dg-final { scan-assembler-times "fsca" 7 } } */
+/* { dg-final { scan-assembler-times "shad" 1 } } */
+/* { dg-final { scan-assembler-times "lds\t" 6 } } */
+/* { dg-final { scan-assembler-times "fmul" 2 } } */
+/* { dg-final { scan-assembler-times "ftrc" 1 } } */
+
+#include <math.h>
+
+static const float pi = 3.14159265359f;
+
+float
+test00 (int x)
+{
+ /* 1x shad, 1x lds, 1x fsca */
+ return sinf ( (x >> 8) * (2*pi) / (1 << 16));
+}
+
+float
+test01 (int x)
+{
+ /* 1x lds, 1x fsca */
+ return sinf (x * (2*pi) / 65536);
+}
+
+float
+test02 (int x)
+{
+ /* 1x lds, 1x fsca */
+ return sinf (x * (2*pi / 65536));
+}
+
+float
+test03 (int x)
+{
+ /* 1x lds, 1x fsca */
+ float scale = 2*pi / 65536;
+ return sinf (x * scale);
+}
+
+float
+test04 (int x)
+{
+ /* 1x lds, 1x fsca */
+ return cosf (x / 65536.0f * 2*pi);
+}
+
+float
+test05 (int x)
+{
+ /* 1x lds, 1x fsca, 1x fmul */
+ float scale = 2*pi / 65536;
+ return sinf (x * scale) * cosf (x * scale);
+}
+
+float
+test_06 (float x)
+{
+ /* 1x fmul, 1x ftrc, 1x fsca */
+ return sinf (x);
+}
diff --git a/gcc/testsuite/gfortran.dg/class_allocate_13.f90 b/gcc/testsuite/gfortran.dg/class_allocate_13.f90
new file mode 100644
index 00000000000..64f37dc59b5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/class_allocate_13.f90
@@ -0,0 +1,31 @@
+! { dg-do run }
+!
+! PR 54784: [4.7/4.8 Regression] [OOP] wrong code in polymorphic allocation with SOURCE
+!
+! Contributed by Jeremy Kozdon <jkozdon@gmail.com>
+
+program bug
+ implicit none
+
+ type :: block
+ real, allocatable :: fields
+ end type
+
+ type :: list
+ class(block),allocatable :: B
+ end type
+
+ type :: domain
+ type(list),dimension(2) :: L
+ end type
+
+ type(domain) :: d
+ type(block) :: b1
+
+ allocate(b1%fields,source=5.)
+
+ allocate(d%L(2)%B,source=b1) ! wrong code
+
+ if (d%L(2)%B%fields/=5.) call abort()
+
+end program
diff --git a/gcc/testsuite/gfortran.dg/dummy_procedure_9.f90 b/gcc/testsuite/gfortran.dg/dummy_procedure_9.f90
new file mode 100644
index 00000000000..16da37f1893
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dummy_procedure_9.f90
@@ -0,0 +1,37 @@
+! { dg-do compile }
+!
+! PR 40453: [F95] Enhanced (recursive) argument checking
+!
+! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
+
+program RecursiveInterface
+
+ call c(b2) ! { dg-error "Interface mismatch in dummy procedure" }
+
+ contains
+
+ subroutine a1(x)
+ real :: x
+ end subroutine
+
+ subroutine a2(i)
+ integer :: i
+ end subroutine
+
+ !!!!!!!!!!!!!!!
+
+ subroutine b1 (f1)
+ procedure(a1) :: f1
+ end subroutine
+
+ subroutine b2 (f2)
+ procedure(a2) :: f2
+ end subroutine
+
+ !!!!!!!!!!!!!!!
+
+ subroutine c(g)
+ procedure(b1) :: g
+ end subroutine
+
+end
diff --git a/gcc/testsuite/gnat.dg/unchecked_convert9.adb b/gcc/testsuite/gnat.dg/unchecked_convert9.adb
new file mode 100644
index 00000000000..133f3b94c6a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/unchecked_convert9.adb
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+-- { dg-options "-O -fdump-rtl-final" }
+
+package body Unchecked_Convert9 is
+
+ procedure Proc is
+ L : Unsigned_32 := 16#55557777#;
+ begin
+ Var := Conv (L);
+ end;
+
+end Unchecked_Convert9;
+
+-- { dg-final { scan-rtl-dump-times "set \\(mem/v" 1 "final" } }
+-- { dg-final { cleanup-rtl-dump "final" } }
diff --git a/gcc/testsuite/gnat.dg/unchecked_convert9.ads b/gcc/testsuite/gnat.dg/unchecked_convert9.ads
new file mode 100644
index 00000000000..d4595f52a02
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/unchecked_convert9.ads
@@ -0,0 +1,20 @@
+with System;
+with Ada.Unchecked_Conversion;
+with Interfaces; use Interfaces;
+
+package Unchecked_Convert9 is
+
+ type R is record
+ H : Unsigned_16;
+ L : Unsigned_16;
+ end record;
+
+ Var : R;
+ pragma Volatile (Var);
+
+ function Conv is new
+ Ada.Unchecked_Conversion (Source => Unsigned_32, Target => R);
+
+ procedure Proc;
+
+end Unchecked_Convert9;
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 9098285267f..f8e416c7090 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -2053,7 +2053,8 @@ proc check_effective_target_arm_vfp_ok { } {
# options.
proc check_effective_target_arm_hard_vfp_ok { } {
- if { [check_effective_target_arm32] } {
+ if { [check_effective_target_arm32]
+ && ! [check-flags [list "" { *-*-* } { "-mfloat-abi=*" } { "-mfloat-abi=hard" }]] } {
return [check_no_compiler_messages arm_hard_vfp_ok executable {
int main() { return 0;}
} "-mfpu=vfp -mfloat-abi=hard"]
diff --git a/gcc/testsuite/obj-c++.dg/tls/init-2.mm b/gcc/testsuite/obj-c++.dg/tls/init-2.mm
index dc886ba0107..327c309e985 100644
--- a/gcc/testsuite/obj-c++.dg/tls/init-2.mm
+++ b/gcc/testsuite/obj-c++.dg/tls/init-2.mm
@@ -2,13 +2,13 @@
/* { dg-require-effective-target tls } */
extern __thread int i;
-__thread int *p = &i; /* { dg-error "dynamically initialized" } */
+__thread int *p = &i; /* { dg-error "dynamic initialization" } */
extern int f();
-__thread int j = f(); /* { dg-error "dynamically initialized" } */
+__thread int j = f(); /* { dg-error "dynamic initialization" } */
struct S
{
S();
};
-__thread S s; /* { dg-error "" } two errors here */
+__thread S s; /* { dg-error "dynamic initialization" } */
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index eb1af4e9e45..b6c5654da01 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2840,6 +2840,8 @@ simplify_vector_constructor (gimple_stmt_iterator *gsi)
{
if (TREE_CODE (ref) != SSA_NAME)
return false;
+ if (!useless_type_conversion_p (type, TREE_TYPE (ref)))
+ return false;
orig = ref;
}
if (TREE_INT_CST_LOW (TREE_OPERAND (op1, 1)) != elem_size)
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index cdcdb5c5ad8..3c39413ee1b 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -2965,6 +2965,7 @@ estimate_numbers_of_iterations_loop (struct loop *loop)
struct tree_niter_desc niter_desc;
edge ex;
double_int bound;
+ edge likely_exit;
/* Give up if we already have tried to compute an estimation. */
if (loop->estimate_state != EST_NOT_COMPUTED)
@@ -2975,6 +2976,7 @@ estimate_numbers_of_iterations_loop (struct loop *loop)
loop->any_estimate = false;
exits = get_loop_exit_edges (loop);
+ likely_exit = single_likely_exit (loop);
FOR_EACH_VEC_ELT (edge, exits, i, ex)
{
if (!number_of_iterations_exit (loop, ex, &niter_desc, false))
@@ -2988,7 +2990,7 @@ estimate_numbers_of_iterations_loop (struct loop *loop)
niter);
record_estimate (loop, niter, niter_desc.max,
last_stmt (ex->src),
- true, true, true);
+ true, ex == likely_exit, true);
}
VEC_free (edge, heap, exits);
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index fe9186cefa9..548c110f6d2 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -2853,7 +2853,7 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
case NARY:
{
vn_nary_op_t nary = PRE_EXPR_NARY (expr);
- tree genop[4];
+ tree *genop = XALLOCAVEC (tree, nary->length);
unsigned i;
for (i = 0; i < nary->length; ++i)
{
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index 2eee50ee1d6..ad64876c339 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -846,9 +846,15 @@ static bool
def_split_header_continue_p (const_basic_block bb, const void *data)
{
const_basic_block new_header = (const_basic_block) data;
- return (bb != new_header
- && (loop_depth (bb->loop_father)
- >= loop_depth (new_header->loop_father)));
+ const struct loop *l;
+
+ if (bb == new_header
+ || loop_depth (bb->loop_father) < loop_depth (new_header->loop_father))
+ return false;
+ for (l = bb->loop_father; l; l = loop_outer (l))
+ if (l == new_header->loop_father)
+ return true;
+ return false;
}
/* Thread jumps through the header of LOOP. Returns true if cfg changes.
diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c
index fc6984583e8..1a615f15174 100644
--- a/gcc/tree-streamer-in.c
+++ b/gcc/tree-streamer-in.c
@@ -68,12 +68,11 @@ input_identifier (struct data_in *data_in, struct lto_input_block *ib)
tree
streamer_read_chain (struct lto_input_block *ib, struct data_in *data_in)
{
- int i, count;
tree first, prev, curr;
+ /* The chain is written as NULL terminated list of trees. */
first = prev = NULL_TREE;
- count = streamer_read_hwi (ib);
- for (i = 0; i < count; i++)
+ do
{
curr = stream_read_tree (ib, data_in);
if (prev)
@@ -81,9 +80,9 @@ streamer_read_chain (struct lto_input_block *ib, struct data_in *data_in)
else
first = curr;
- TREE_CHAIN (curr) = NULL_TREE;
prev = curr;
}
+ while (curr);
return first;
}
@@ -179,7 +178,6 @@ unpack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr)
TREE_FIXED_CST_PTR (expr) = fp;
}
-
/* Unpack all the non-pointer fields of the TS_DECL_COMMON structure
of expression EXPR from bitpack BP. */
@@ -355,24 +353,60 @@ unpack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
of expression EXPR from bitpack BP. */
static void
-unpack_ts_block_value_fields (struct bitpack_d *bp, tree expr)
+unpack_ts_block_value_fields (struct data_in *data_in,
+ struct bitpack_d *bp, tree expr)
{
BLOCK_ABSTRACT (expr) = (unsigned) bp_unpack_value (bp, 1);
/* BLOCK_NUMBER is recomputed. */
+ BLOCK_SOURCE_LOCATION (expr) = stream_input_location (bp, data_in);
}
/* Unpack all the non-pointer fields of the TS_TRANSLATION_UNIT_DECL
structure of expression EXPR from bitpack BP. */
static void
-unpack_ts_translation_unit_decl_value_fields (struct bitpack_d *bp ATTRIBUTE_UNUSED, tree expr ATTRIBUTE_UNUSED)
+unpack_ts_translation_unit_decl_value_fields (struct data_in *data_in,
+ struct bitpack_d *bp, tree expr)
{
+ TRANSLATION_UNIT_LANGUAGE (expr) = xstrdup (bp_unpack_string (data_in, bp));
+ VEC_safe_push (tree, gc, all_translation_units, expr);
}
+/* Unpack a TS_TARGET_OPTION tree from BP into EXPR. */
+
+static void
+unpack_ts_target_option (struct bitpack_d *bp, tree expr)
+{
+ unsigned i, len;
+ struct cl_target_option *t = TREE_TARGET_OPTION (expr);
+
+ len = sizeof (struct cl_target_option);
+ for (i = 0; i < len; i++)
+ ((unsigned char *)t)[i] = bp_unpack_value (bp, 8);
+ if (bp_unpack_value (bp, 32) != 0x12345678)
+ fatal_error ("cl_target_option size mismatch in LTO reader and writer");
+}
+
+/* Unpack a TS_OPTIMIZATION tree from BP into EXPR. */
+
+static void
+unpack_ts_optimization (struct bitpack_d *bp, tree expr)
+{
+ unsigned i, len;
+ struct cl_optimization *t = TREE_OPTIMIZATION (expr);
+
+ len = sizeof (struct cl_optimization);
+ for (i = 0; i < len; i++)
+ ((unsigned char *)t)[i] = bp_unpack_value (bp, 8);
+ if (bp_unpack_value (bp, 32) != 0x12345678)
+ fatal_error ("cl_optimization size mismatch in LTO reader and writer");
+}
+
+
/* Unpack all the non-pointer fields in EXPR into a bit pack. */
static void
-unpack_value_fields (struct bitpack_d *bp, tree expr)
+unpack_value_fields (struct data_in *data_in, struct bitpack_d *bp, tree expr)
{
enum tree_code code;
@@ -388,6 +422,9 @@ unpack_value_fields (struct bitpack_d *bp, tree expr)
if (CODE_CONTAINS_STRUCT (code, TS_FIXED_CST))
unpack_ts_fixed_cst_value_fields (bp, expr);
+ if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL))
+ DECL_SOURCE_LOCATION (expr) = stream_input_location (bp, data_in);
+
if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
unpack_ts_decl_common_value_fields (bp, expr);
@@ -403,11 +440,34 @@ unpack_value_fields (struct bitpack_d *bp, tree expr)
if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
unpack_ts_type_common_value_fields (bp, expr);
+ if (CODE_CONTAINS_STRUCT (code, TS_EXP))
+ SET_EXPR_LOCATION (expr, stream_input_location (bp, data_in));
+
if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
- unpack_ts_block_value_fields (bp, expr);
+ unpack_ts_block_value_fields (data_in, bp, expr);
if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
- unpack_ts_translation_unit_decl_value_fields (bp, expr);
+ unpack_ts_translation_unit_decl_value_fields (data_in, bp, expr);
+
+ if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
+ unpack_ts_target_option (bp, expr);
+
+ if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
+ unpack_ts_optimization (bp, expr);
+
+ if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
+ {
+ unsigned HOST_WIDE_INT length = bp_unpack_var_len_unsigned (bp);
+ if (length > 0)
+ VEC_safe_grow (tree, gc, BINFO_BASE_ACCESSES (expr), length);
+ }
+
+ if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
+ {
+ unsigned HOST_WIDE_INT length = bp_unpack_var_len_unsigned (bp);
+ if (length > 0)
+ VEC_safe_grow (constructor_elt, gc, CONSTRUCTOR_ELTS (expr), length);
+ }
}
@@ -416,7 +476,8 @@ unpack_value_fields (struct bitpack_d *bp, tree expr)
bitfield values that the writer may have written. */
struct bitpack_d
-streamer_read_tree_bitfields (struct lto_input_block *ib, tree expr)
+streamer_read_tree_bitfields (struct lto_input_block *ib,
+ struct data_in *data_in, tree expr)
{
enum tree_code code;
struct bitpack_d bp;
@@ -431,7 +492,7 @@ streamer_read_tree_bitfields (struct lto_input_block *ib, tree expr)
lto_tree_code_to_tag (TREE_CODE (expr)));
/* Unpack all the value fields from BP. */
- unpack_value_fields (&bp, expr);
+ unpack_value_fields (data_in, &bp, expr);
return bp;
}
@@ -563,7 +624,6 @@ lto_input_ts_decl_minimal_tree_pointers (struct lto_input_block *ib,
{
DECL_NAME (expr) = stream_read_tree (ib, data_in);
DECL_CONTEXT (expr) = stream_read_tree (ib, data_in);
- DECL_SOURCE_LOCATION (expr) = lto_input_location (ib, data_in);
}
@@ -769,17 +829,11 @@ static void
lto_input_ts_exp_tree_pointers (struct lto_input_block *ib,
struct data_in *data_in, tree expr)
{
- int i, length;
- location_t loc;
-
- length = streamer_read_hwi (ib);
- gcc_assert (length == TREE_OPERAND_LENGTH (expr));
+ int i;
- for (i = 0; i < length; i++)
+ for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
TREE_OPERAND (expr, i) = stream_read_tree (ib, data_in);
- loc = lto_input_location (ib, data_in);
- SET_EXPR_LOCATION (expr, loc);
TREE_SET_BLOCK (expr, stream_read_tree (ib, data_in));
}
@@ -801,7 +855,6 @@ lto_input_ts_block_tree_pointers (struct lto_input_block *ib,
function scopes. For the rest them on the floor instead of ICEing in
dwarf2out.c. */
BLOCK_ABSTRACT_ORIGIN (expr) = stream_read_tree (ib, data_in);
- BLOCK_SOURCE_LOCATION (expr) = lto_input_location (ib, data_in);
/* Do not stream BLOCK_NONLOCALIZED_VARS. We cannot handle debug information
for early inlined BLOCKs so drop it on the floor instead of ICEing in
dwarf2out.c. */
@@ -838,7 +891,7 @@ static void
lto_input_ts_binfo_tree_pointers (struct lto_input_block *ib,
struct data_in *data_in, tree expr)
{
- unsigned i, len;
+ unsigned i;
tree t;
/* Note that the number of slots in EXPR was read in
@@ -858,15 +911,12 @@ lto_input_ts_binfo_tree_pointers (struct lto_input_block *ib,
BINFO_VTABLE (expr) = stream_read_tree (ib, data_in);
BINFO_VPTR_FIELD (expr) = stream_read_tree (ib, data_in);
- len = streamer_read_uhwi (ib);
- if (len > 0)
+ /* The vector of BINFO_BASE_ACCESSES is pre-allocated during
+ unpacking the bitfield section. */
+ for (i = 0; i < VEC_length (tree, BINFO_BASE_ACCESSES (expr)); i++)
{
- VEC_reserve_exact (tree, gc, BINFO_BASE_ACCESSES (expr), len);
- for (i = 0; i < len; i++)
- {
- tree a = stream_read_tree (ib, data_in);
- VEC_quick_push (tree, BINFO_BASE_ACCESSES (expr), a);
- }
+ tree a = stream_read_tree (ib, data_in);
+ VEC_replace (tree, BINFO_BASE_ACCESSES (expr), i, a);
}
BINFO_INHERITANCE_CHAIN (expr) = stream_read_tree (ib, data_in);
@@ -883,65 +933,18 @@ static void
lto_input_ts_constructor_tree_pointers (struct lto_input_block *ib,
struct data_in *data_in, tree expr)
{
- unsigned i, len;
+ unsigned i;
- len = streamer_read_uhwi (ib);
- for (i = 0; i < len; i++)
+ for (i = 0; i < CONSTRUCTOR_NELTS (expr); i++)
{
- tree index, value;
-
- index = stream_read_tree (ib, data_in);
- value = stream_read_tree (ib, data_in);
- CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (expr), index, value);
+ constructor_elt e;
+ e.index = stream_read_tree (ib, data_in);
+ e.value = stream_read_tree (ib, data_in);
+ VEC_replace (constructor_elt, CONSTRUCTOR_ELTS (expr), i, e);
}
}
-/* Input a TS_TARGET_OPTION tree from IB into EXPR. */
-
-static void
-lto_input_ts_target_option (struct lto_input_block *ib, tree expr)
-{
- unsigned i, len;
- struct bitpack_d bp;
- struct cl_target_option *t = TREE_TARGET_OPTION (expr);
-
- bp = streamer_read_bitpack (ib);
- len = sizeof (struct cl_target_option);
- for (i = 0; i < len; i++)
- ((unsigned char *)t)[i] = bp_unpack_value (&bp, 8);
- if (bp_unpack_value (&bp, 32) != 0x12345678)
- fatal_error ("cl_target_option size mismatch in LTO reader and writer");
-}
-
-/* Input a TS_OPTIMIZATION tree from IB into EXPR. */
-
-static void
-lto_input_ts_optimization (struct lto_input_block *ib, tree expr)
-{
- unsigned i, len;
- struct bitpack_d bp;
- struct cl_optimization *t = TREE_OPTIMIZATION (expr);
-
- bp = streamer_read_bitpack (ib);
- len = sizeof (struct cl_optimization);
- for (i = 0; i < len; i++)
- ((unsigned char *)t)[i] = bp_unpack_value (&bp, 8);
- if (bp_unpack_value (&bp, 32) != 0x12345678)
- fatal_error ("cl_optimization size mismatch in LTO reader and writer");
-}
-
-/* Input a TS_TRANSLATION_UNIT_DECL tree from IB and DATA_IN into EXPR. */
-
-static void
-lto_input_ts_translation_unit_decl_tree_pointers (struct lto_input_block *ib,
- struct data_in *data_in,
- tree expr)
-{
- TRANSLATION_UNIT_LANGUAGE (expr) = xstrdup (streamer_read_string (data_in, ib));
- VEC_safe_push (tree, gc, all_translation_units, expr);
-}
-
/* Read all pointer fields in EXPR from input block IB. DATA_IN
contains tables and descriptors for the file being read. */
@@ -1003,15 +1006,6 @@ streamer_read_tree_body (struct lto_input_block *ib, struct data_in *data_in,
if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
lto_input_ts_constructor_tree_pointers (ib, data_in, expr);
-
- if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
- lto_input_ts_target_option (ib, expr);
-
- if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
- lto_input_ts_optimization (ib, expr);
-
- if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
- lto_input_ts_translation_unit_decl_tree_pointers (ib, data_in, expr);
}
diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c
index 4fccd7720d2..dcde16951d9 100644
--- a/gcc/tree-streamer-out.c
+++ b/gcc/tree-streamer-out.c
@@ -145,7 +145,6 @@ pack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr)
bp_pack_var_len_int (bp, fv.data.high);
}
-
/* Pack all the non-pointer fields of the TS_DECL_COMMON structure
of expression EXPR into bitpack BP. */
@@ -299,25 +298,72 @@ pack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
of expression EXPR into bitpack BP. */
static void
-pack_ts_block_value_fields (struct bitpack_d *bp, tree expr)
+pack_ts_block_value_fields (struct output_block *ob,
+ struct bitpack_d *bp, tree expr)
{
bp_pack_value (bp, BLOCK_ABSTRACT (expr), 1);
/* BLOCK_NUMBER is recomputed. */
+ /* Stream BLOCK_SOURCE_LOCATION for the limited cases we can handle - those
+ that represent inlined function scopes.
+ For the rest them on the floor instead of ICEing in dwarf2out.c. */
+ if (inlined_function_outer_scope_p (expr))
+ stream_output_location (ob, bp, BLOCK_SOURCE_LOCATION (expr));
+ else
+ stream_output_location (ob, bp, UNKNOWN_LOCATION);
}
/* Pack all the non-pointer fields of the TS_TRANSLATION_UNIT_DECL structure
of expression EXPR into bitpack BP. */
static void
-pack_ts_translation_unit_decl_value_fields (struct bitpack_d *bp ATTRIBUTE_UNUSED, tree expr ATTRIBUTE_UNUSED)
+pack_ts_translation_unit_decl_value_fields (struct output_block *ob,
+ struct bitpack_d *bp, tree expr)
+{
+ bp_pack_string (ob, bp, TRANSLATION_UNIT_LANGUAGE (expr), true);
+}
+
+/* Pack a TS_TARGET_OPTION tree in EXPR to BP. */
+
+static void
+pack_ts_target_option (struct bitpack_d *bp, tree expr)
+{
+ struct cl_target_option *t = TREE_TARGET_OPTION (expr);
+ unsigned i, len;
+
+ /* The cl_target_option is target specific and generated by the options
+ awk script, so we just recreate a byte-by-byte copy here. */
+
+ len = sizeof (struct cl_target_option);
+ for (i = 0; i < len; i++)
+ bp_pack_value (bp, ((unsigned char *)t)[i], 8);
+ /* Catch struct size mismatches between reader and writer. */
+ bp_pack_value (bp, 0x12345678, 32);
+}
+
+/* Pack a TS_OPTIMIZATION tree in EXPR to BP. */
+
+static void
+pack_ts_optimization (struct bitpack_d *bp, tree expr)
{
+ struct cl_optimization *t = TREE_OPTIMIZATION (expr);
+ unsigned i, len;
+
+ /* The cl_optimization is generated by the options
+ awk script, so we just recreate a byte-by-byte copy here. */
+
+ len = sizeof (struct cl_optimization);
+ for (i = 0; i < len; i++)
+ bp_pack_value (bp, ((unsigned char *)t)[i], 8);
+ /* Catch struct size mismatches between reader and writer. */
+ bp_pack_value (bp, 0x12345678, 32);
}
/* Pack all the bitfields in EXPR into a bit pack. */
void
-streamer_pack_tree_bitfields (struct bitpack_d *bp, tree expr)
+streamer_pack_tree_bitfields (struct output_block *ob,
+ struct bitpack_d *bp, tree expr)
{
enum tree_code code;
@@ -333,6 +379,9 @@ streamer_pack_tree_bitfields (struct bitpack_d *bp, tree expr)
if (CODE_CONTAINS_STRUCT (code, TS_FIXED_CST))
pack_ts_fixed_cst_value_fields (bp, expr);
+ if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL))
+ stream_output_location (ob, bp, DECL_SOURCE_LOCATION (expr));
+
if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
pack_ts_decl_common_value_fields (bp, expr);
@@ -348,11 +397,26 @@ streamer_pack_tree_bitfields (struct bitpack_d *bp, tree expr)
if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
pack_ts_type_common_value_fields (bp, expr);
+ if (CODE_CONTAINS_STRUCT (code, TS_EXP))
+ stream_output_location (ob, bp, EXPR_LOCATION (expr));
+
if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
- pack_ts_block_value_fields (bp, expr);
+ pack_ts_block_value_fields (ob, bp, expr);
if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
- pack_ts_translation_unit_decl_value_fields (bp, expr);
+ pack_ts_translation_unit_decl_value_fields (ob, bp, expr);
+
+ if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
+ pack_ts_target_option (bp, expr);
+
+ if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
+ pack_ts_optimization (bp, expr);
+
+ if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
+ bp_pack_var_len_unsigned (bp, VEC_length (tree, BINFO_BASE_ACCESSES (expr)));
+
+ if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
+ bp_pack_var_len_unsigned (bp, CONSTRUCTOR_NELTS (expr));
}
@@ -398,11 +462,7 @@ streamer_write_builtin (struct output_block *ob, tree expr)
void
streamer_write_chain (struct output_block *ob, tree t, bool ref_p)
{
- int i, count;
-
- count = list_length (t);
- streamer_write_hwi (ob, count);
- for (i = 0; i < count; i++)
+ while (t)
{
tree saved_chain;
@@ -424,6 +484,9 @@ streamer_write_chain (struct output_block *ob, tree t, bool ref_p)
TREE_CHAIN (t) = saved_chain;
t = TREE_CHAIN (t);
}
+
+ /* Write a sentinel to terminate the chain. */
+ stream_write_tree (ob, NULL_TREE, ref_p);
}
@@ -476,7 +539,6 @@ write_ts_decl_minimal_tree_pointers (struct output_block *ob, tree expr,
{
stream_write_tree (ob, DECL_NAME (expr), ref_p);
stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
- lto_output_location (ob, LOCATION_LOCUS (DECL_SOURCE_LOCATION (expr)));
}
@@ -670,10 +732,8 @@ write_ts_exp_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
{
int i;
- streamer_write_hwi (ob, TREE_OPERAND_LENGTH (expr));
for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
- lto_output_location (ob, LOCATION_LOCUS (EXPR_LOCATION (expr)));
stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
}
@@ -689,21 +749,16 @@ write_ts_block_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
stream_write_tree (ob, BLOCK_SUPERCONTEXT (expr), ref_p);
- /* Stream BLOCK_ABSTRACT_ORIGIN and BLOCK_SOURCE_LOCATION for
- the limited cases we can handle - those that represent inlined
- function scopes. For the rest them on the floor instead of ICEing in
- dwarf2out.c. */
+ /* Stream BLOCK_ABSTRACT_ORIGIN for the limited cases we can handle - those
+ that represent inlined function scopes.
+ For the rest them on the floor instead of ICEing in dwarf2out.c. */
if (inlined_function_outer_scope_p (expr))
{
tree ultimate_origin = block_ultimate_origin (expr);
stream_write_tree (ob, ultimate_origin, ref_p);
- lto_output_location (ob, BLOCK_SOURCE_LOCATION (expr));
}
else
- {
- stream_write_tree (ob, NULL_TREE, ref_p);
- lto_output_location (ob, UNKNOWN_LOCATION);
- }
+ stream_write_tree (ob, NULL_TREE, ref_p);
/* Do not stream BLOCK_NONLOCALIZED_VARS. We cannot handle debug information
for early inlined BLOCKs so drop it on the floor instead of ICEing in
dwarf2out.c. */
@@ -737,7 +792,8 @@ write_ts_binfo_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
stream_write_tree (ob, BINFO_VTABLE (expr), ref_p);
stream_write_tree (ob, BINFO_VPTR_FIELD (expr), ref_p);
- streamer_write_uhwi (ob, VEC_length (tree, BINFO_BASE_ACCESSES (expr)));
+ /* The number of BINFO_BASE_ACCESSES has already been emitted in
+ EXPR's bitfield section. */
FOR_EACH_VEC_ELT (tree, BINFO_BASE_ACCESSES (expr), i, t)
stream_write_tree (ob, t, ref_p);
@@ -758,7 +814,6 @@ write_ts_constructor_tree_pointers (struct output_block *ob, tree expr,
unsigned i;
tree index, value;
- streamer_write_uhwi (ob, CONSTRUCTOR_NELTS (expr));
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (expr), i, index, value)
{
stream_write_tree (ob, index, ref_p);
@@ -766,58 +821,6 @@ write_ts_constructor_tree_pointers (struct output_block *ob, tree expr,
}
}
-/* Write a TS_TARGET_OPTION tree in EXPR to OB. */
-
-static void
-write_ts_target_option (struct output_block *ob, tree expr)
-{
- struct cl_target_option *t = TREE_TARGET_OPTION (expr);
- struct bitpack_d bp;
- unsigned i, len;
-
- /* The cl_target_option is target specific and generated by the options
- awk script, so we just recreate a byte-by-byte copy here. */
-
- bp = bitpack_create (ob->main_stream);
- len = sizeof (struct cl_target_option);
- for (i = 0; i < len; i++)
- bp_pack_value (&bp, ((unsigned char *)t)[i], 8);
- /* Catch struct size mismatches between reader and writer. */
- bp_pack_value (&bp, 0x12345678, 32);
- streamer_write_bitpack (&bp);
-}
-
-/* Write a TS_OPTIMIZATION tree in EXPR to OB. */
-
-static void
-write_ts_optimization (struct output_block *ob, tree expr)
-{
- struct cl_optimization *t = TREE_OPTIMIZATION (expr);
- struct bitpack_d bp;
- unsigned i, len;
-
- /* The cl_optimization is generated by the options
- awk script, so we just recreate a byte-by-byte copy here. */
-
- bp = bitpack_create (ob->main_stream);
- len = sizeof (struct cl_optimization);
- for (i = 0; i < len; i++)
- bp_pack_value (&bp, ((unsigned char *)t)[i], 8);
- /* Catch struct size mismatches between reader and writer. */
- bp_pack_value (&bp, 0x12345678, 32);
- streamer_write_bitpack (&bp);
-}
-
-/* Write a TS_TRANSLATION_UNIT_DECL tree in EXPR to OB. */
-
-static void
-write_ts_translation_unit_decl_tree_pointers (struct output_block *ob,
- tree expr)
-{
- streamer_write_string (ob, ob->main_stream,
- TRANSLATION_UNIT_LANGUAGE (expr), true);
-}
-
/* Write all pointer fields in EXPR to output block OB. If REF_P is true,
the leaves of EXPR are emitted as references. */
@@ -878,15 +881,6 @@ streamer_write_tree_body (struct output_block *ob, tree expr, bool ref_p)
if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
write_ts_constructor_tree_pointers (ob, expr, ref_p);
-
- if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
- write_ts_target_option (ob, expr);
-
- if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
- write_ts_optimization (ob, expr);
-
- if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
- write_ts_translation_unit_decl_tree_pointers (ob, expr);
}
diff --git a/gcc/tree-streamer.h b/gcc/tree-streamer.h
index be0b1a3f95d..778712b3e20 100644
--- a/gcc/tree-streamer.h
+++ b/gcc/tree-streamer.h
@@ -72,14 +72,16 @@ void streamer_read_tree_body (struct lto_input_block *, struct data_in *, tree);
tree streamer_get_pickled_tree (struct lto_input_block *, struct data_in *);
tree streamer_get_builtin_tree (struct lto_input_block *, struct data_in *);
tree streamer_read_integer_cst (struct lto_input_block *, struct data_in *);
-struct bitpack_d streamer_read_tree_bitfields (struct lto_input_block *, tree);
+struct bitpack_d streamer_read_tree_bitfields (struct lto_input_block *,
+ struct data_in *, tree);
/* In tree-streamer-out.c. */
void streamer_write_string_cst (struct output_block *,
struct lto_output_stream *, tree);
void streamer_write_chain (struct output_block *, tree, bool);
void streamer_write_tree_header (struct output_block *, tree);
-void streamer_pack_tree_bitfields (struct bitpack_d *, tree);
+void streamer_pack_tree_bitfields (struct output_block *, struct bitpack_d *,
+ tree);
void streamer_write_tree_body (struct output_block *, tree, bool);
void streamer_write_integer_cst (struct output_block *, tree, bool);
void streamer_write_builtin (struct output_block *, tree);
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 58edfcbe480..6b8ba3f7091 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -2382,7 +2382,7 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
if (orig_code == MINUS_EXPR)
{
tree rhs = gimple_assign_rhs2 (def_stmt);
- tree negrhs = copy_ssa_name (rhs, NULL);
+ tree negrhs = make_ssa_name (TREE_TYPE (rhs), NULL);
gimple negate_stmt = gimple_build_assign_with_ops (NEGATE_EXPR, negrhs,
rhs, NULL);
gimple_stmt_iterator gsi = gsi_for_stmt (def_stmt);
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 92eaac48a41..e1b7b7a0e7b 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -6060,11 +6060,6 @@ get_vectype_for_scalar_type_and_size (tree scalar_type, unsigned size)
&& GET_MODE_CLASS (inner_mode) != MODE_FLOAT)
return NULL_TREE;
- /* We can't build a vector type of elements with alignment bigger than
- their size. */
- if (nbytes < TYPE_ALIGN_UNIT (scalar_type))
- return NULL_TREE;
-
/* For vector types of elements whose mode precision doesn't
match their types precision we use a element type of mode
precision. The vectorization routines will have to make sure
@@ -6086,6 +6081,11 @@ get_vectype_for_scalar_type_and_size (tree scalar_type, unsigned size)
&& !POINTER_TYPE_P (scalar_type))
scalar_type = lang_hooks.types.type_for_mode (inner_mode, 1);
+ /* We can't build a vector type of elements with alignment bigger than
+ their size. */
+ if (nbytes < TYPE_ALIGN_UNIT (scalar_type))
+ scalar_type = lang_hooks.types.type_for_mode (inner_mode, 1);
+
/* If no size was supplied use the mode the target prefers. Otherwise
lookup a vector mode of the specified size. */
if (size == 0)
diff --git a/gcc/tree.def b/gcc/tree.def
index 70188ff0524..0f470006a70 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -1093,8 +1093,11 @@ DEFTREECODE (TRANSACTION_EXPR, "transaction_expr", tcc_expression, 1)
Operations that take a vector of elements and "reduce" it to a scalar
result (e.g. summing the elements of the vector, finding the minimum over
the vector elements, etc).
- Operand 0 is a vector; the first element in the vector has the result.
- Operand 1 is a vector. */
+ Operand 0 is a vector.
+ The expression returns a vector of the same type, with the first
+ element in the vector holding the result of the reduction of all elements
+ of the operand. The content of the other elements in the returned vector
+ is undefined. */
DEFTREECODE (REDUC_MAX_EXPR, "reduc_max_expr", tcc_unary, 1)
DEFTREECODE (REDUC_MIN_EXPR, "reduc_min_expr", tcc_unary, 1)
DEFTREECODE (REDUC_PLUS_EXPR, "reduc_plus_expr", tcc_unary, 1)
diff --git a/gcc/web.c b/gcc/web.c
index ca822df407e..f15012c2a91 100644
--- a/gcc/web.c
+++ b/gcc/web.c
@@ -1,6 +1,6 @@
/* Web construction code for GNU compiler.
Contributed by Jan Hubicka.
- Copyright (C) 2001, 2002, 2004, 2006, 2007, 2008, 2010
+ Copyright (C) 2001, 2002, 2004, 2006, 2007, 2008, 2010, 2012
Free Software Foundation, Inc.
This file is part of GCC.
@@ -96,6 +96,7 @@ union_match_dups (rtx insn, struct web_entry *def_entry,
struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
df_ref *use_link = DF_INSN_INFO_USES (insn_info);
df_ref *def_link = DF_INSN_INFO_DEFS (insn_info);
+ struct web_entry *dup_entry;
int i;
extract_insn (insn);
@@ -107,10 +108,24 @@ union_match_dups (rtx insn, struct web_entry *def_entry,
df_ref *ref, *dupref;
struct web_entry *entry;
- for (dupref = use_link; *dupref; dupref++)
+ for (dup_entry = use_entry, dupref = use_link; *dupref; dupref++)
if (DF_REF_LOC (*dupref) == recog_data.dup_loc[i])
break;
+ if (*dupref == NULL && type == OP_INOUT)
+ {
+
+ for (dup_entry = def_entry, dupref = def_link; *dupref; dupref++)
+ if (DF_REF_LOC (*dupref) == recog_data.dup_loc[i])
+ break;
+ }
+ /* ??? *DUPREF can still be zero, because when an operand matches
+ a memory, DF_REF_LOC (use_link[n]) points to the register part
+ of the address, whereas recog_data.dup_loc[m] points to the
+ entire memory ref, thus we fail to find the duplicate entry,
+ even though it is there.
+ Example: i686-pc-linux-gnu gcc.c-torture/compile/950607-1.c
+ -O3 -fomit-frame-pointer -funroll-loops */
if (*dupref == NULL
|| DF_REF_REGNO (*dupref) < FIRST_PSEUDO_REGISTER)
continue;
@@ -121,7 +136,15 @@ union_match_dups (rtx insn, struct web_entry *def_entry,
if (DF_REF_LOC (*ref) == recog_data.operand_loc[op])
break;
- (*fun) (use_entry + DF_REF_ID (*dupref), entry + DF_REF_ID (*ref));
+ if (!*ref && type == OP_INOUT)
+ {
+ for (ref = use_link, entry = use_entry; *ref; ref++)
+ if (DF_REF_LOC (*ref) == recog_data.operand_loc[op])
+ break;
+ }
+
+ gcc_assert (*ref);
+ (*fun) (dup_entry + DF_REF_ID (*dupref), entry + DF_REF_ID (*ref));
}
}
@@ -317,7 +340,8 @@ web_main (void)
rtx insn;
df_set_flags (DF_NO_HARD_REGS + DF_EQ_NOTES);
- df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
+ /* We can not RD_PRUNE_DEAD_DEFS, because we care about REG_EQUAL
+ notes. */
df_chain_add_problem (DF_UD_CHAIN);
df_analyze ();
df_set_flags (DF_DEFER_INSN_RESCAN);