aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2015-01-16 19:05:07 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2015-01-16 19:05:07 +0000
commitdd8982995c957bd6664abba15e9b846ad89f1837 (patch)
tree5906c6e4172e382866e8aa21071b2ee78f9377ef
parent38b3ff4afb12b031ebed05d98d8427fd429dc579 (diff)
parent77688d70590330ad4b56d6fb690456d72406c6a2 (diff)
downloadgcc-dd8982995c957bd6664abba15e9b846ad89f1837.zip
gcc-dd8982995c957bd6664abba15e9b846ad89f1837.tar.gz
gcc-dd8982995c957bd6664abba15e9b846ad89f1837.tar.bz2
Merge from trunk revision 219753.
From-SVN: r219769
-rw-r--r--ChangeLog4
-rw-r--r--MAINTAINERS1
-rw-r--r--gcc/ChangeLog207
-rw-r--r--gcc/ada/gcc-interface/utils.c2
-rw-r--r--gcc/builtins.c2
-rw-r--r--gcc/ccmp.c123
-rw-r--r--gcc/config/aarch64/aarch64-cores.def2
-rw-r--r--gcc/config/aarch64/aarch64-tune.md2
-rw-r--r--gcc/config/aarch64/aarch64.c202
-rw-r--r--gcc/config/aarch64/aarch64.md26
-rw-r--r--gcc/config/aarch64/aarch64.opt4
-rw-r--r--gcc/config/arm/cortex-a57.md797
-rw-r--r--gcc/config/i386/avx2intrin.h18
-rw-r--r--gcc/config/i386/emmintrin.h16
-rw-r--r--gcc/config/nds32/constants.md1
-rw-r--r--gcc/config/nds32/nds32-protos.h8
-rw-r--r--gcc/config/nds32/nds32.c52
-rw-r--r--gcc/config/nds32/nds32.md154
-rw-r--r--gcc/config/rs6000/default64.h2
-rw-r--r--gcc/config/rs6000/rs6000.c36
-rw-r--r--gcc/config/rs6000/rs6000.h2
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/pt.c2
-rw-r--r--gcc/cp/tree.c4
-rw-r--r--gcc/doc/invoke.texi41
-rw-r--r--gcc/doc/tm.texi25
-rw-r--r--gcc/expmed.c15
-rw-r--r--gcc/fortran/ChangeLog6
-rw-r--r--gcc/fortran/decl.c4
-rw-r--r--gcc/ipa-chkp.c39
-rw-r--r--gcc/ipa-chkp.h1
-rw-r--r--gcc/ipa-inline.c13
-rw-r--r--gcc/jit/ChangeLog9
-rw-r--r--gcc/jit/jit-builtins.c11
-rw-r--r--gcc/jit/jit-builtins.h9
-rw-r--r--gcc/lra-constraints.c2
-rw-r--r--gcc/optc-save-gen.awk6
-rw-r--r--gcc/params.def2
-rw-r--r--gcc/simplify-rtx.c12
-rw-r--r--gcc/target.def25
-rw-r--r--gcc/testsuite/ChangeLog76
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/auto44.C10
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr64612.C66
-rw-r--r--gcc/testsuite/g++.dg/pr64353.C15
-rw-r--r--gcc/testsuite/g++.dg/torture/pr64568-2.C146
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20150108.c23
-rw-r--r--gcc/testsuite/gcc.dg/builtin-apply2.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr64015.c10
-rw-r--r--gcc/testsuite/gcc.dg/pr64434.c (renamed from gcc/testsuite/gcc.dg/torture/pr64434.c)0
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr61743-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr61743-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/uninit-18.c24
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr64263_1.c23
-rw-r--r--gcc/testsuite/gcc.target/i386/chkp-label-address.c24
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-14.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-22.c4
-rw-r--r--gcc/testsuite/gcc.target/visium/bit_shift.c13
-rw-r--r--gcc/testsuite/gcc.target/visium/bit_test.c31
-rw-r--r--gcc/testsuite/gcc.target/visium/block_move.c19
-rw-r--r--gcc/testsuite/gcc.target/visium/cstore_eq.c25
-rw-r--r--gcc/testsuite/gcc.target/visium/cstore_fp.c25
-rw-r--r--gcc/testsuite/gcc.target/visium/cstore_uns.c25
-rw-r--r--gcc/testsuite/gcc.target/visium/long_branch.c27
-rw-r--r--gcc/testsuite/gcc.target/visium/loop_clear.c15
-rw-r--r--gcc/testsuite/gcc.target/visium/visium.exp44
-rw-r--r--gcc/testsuite/gfortran.dg/pointer_init_6.f901
-rw-r--r--gcc/tree-cfg.c2
-rw-r--r--gcc/tree-chkp.c5
-rw-r--r--gcc/tree-inline.c2
-rw-r--r--gcc/tree-inline.h1
-rw-r--r--gcc/tree-ssa-forwprop.c2
-rw-r--r--gcc/tree-ssa-uninit.c87
-rw-r--r--libatomic/ChangeLog6
-rw-r--r--libatomic/testsuite/lib/libatomic.exp6
-rw-r--r--libatomic/testsuite/libatomic.c/c.exp1
-rw-r--r--libgo/Makefile.am4
-rw-r--r--libgo/Makefile.in5
-rw-r--r--libgo/go/net/tcpsockopt_solaris.go27
-rw-r--r--libgomp/ChangeLog4
-rw-r--r--libgomp/target.c2
-rw-r--r--libstdc++-v3/ChangeLog25
-rw-r--r--libstdc++-v3/acinclude.m42
-rw-r--r--libstdc++-v3/config/abi/pre/gnu.ver5
-rwxr-xr-xlibstdc++-v3/configure2
-rw-r--r--libstdc++-v3/include/bits/codecvt.h124
-rw-r--r--libstdc++-v3/include/bits/locale_facets.h5
-rw-r--r--libstdc++-v3/include/std/shared_mutex183
-rw-r--r--libstdc++-v3/src/c++11/Makefile.am1
-rw-r--r--libstdc++-v3/src/c++11/Makefile.in13
-rw-r--r--libstdc++-v3/src/c++11/codecvt.cc461
-rw-r--r--libstdc++-v3/src/c++98/Makefile.am10
-rw-r--r--libstdc++-v3/src/c++98/Makefile.in10
-rw-r--r--libstdc++-v3/src/c++98/locale_init.cc21
-rw-r--r--libstdc++-v3/src/c++98/localename.cc9
-rw-r--r--libstdc++-v3/testsuite/22_locale/codecvt/utf8.cc76
-rw-r--r--libstdc++-v3/testsuite/22_locale/locale/cons/unicode.cc10
96 files changed, 3446 insertions, 217 deletions
diff --git a/ChangeLog b/ChangeLog
index de04d6b..76b28ca 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2015-01-15 Martin Uecker <uecker@eecs.berkeley.edu>
+
+ * MAINTAINERS: (Write After Approval): Add myself.
+
2015-01-15 Philipp Tomsich <ptomsich@theobroma-systems.com>
* MAINTAINERS: (Write After Approval): Add myself.
diff --git a/MAINTAINERS b/MAINTAINERS
index efa87bd..d6e8284 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -576,6 +576,7 @@ Ilya Tocar <tocarip@gmail.com>
Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Konrad Trifunovic <konrad.trifunovic@inria.fr>
Markus Trippelsdorf <markus@trippelsdorf.de>
+Martin Uecker <uecker@eecs.berkeley.edu>
David Ung <davidu@mips.com>
Neil Vachharajani <nvachhar@gmail.com>
Kris Van Hees <kris.van.hees@oracle.com>
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 62735a7..55e0315 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,204 @@
+2015-01-16 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/rs6000.c (TARGET_LIBGCC_CMP_RETURN_MODE,
+ TARGET_LIBGCC_SHIFT_COUNT_MODE, TARGET_UNWIND_WORD_MODE): Implement
+ as ...
+ (rs6000_abi_word_mode): New function.
+
+2015-01-16 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/rs6000.c (rs6000_va_start): Use MIN_UNITS_PER_WORD
+ instead of UNITS_PER_WORD to describe the size of stack slots.
+
+2015-01-16 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/rs6000.c (TARGET_PROMOTE_FUNCTION_MODE): Implement
+ as rs6000_promote_function_mode. Move comment to there.
+ (rs6000_promote_function_mode): New function.
+
+2015-01-16 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/rs6000.h (PROMOTE_MODE): Correct test for when -m32
+ -mpowerpc64 is active.
+
+2015-01-16 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR middle-end/64353
+ * tree-cfg.c (pass_data_fixup_cfg): Update SSA for
+ virtuals on start.
+
+2015-01-16 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/arm/cortex-a57.md: Remove duplicate of file accidentally
+ introduced in revision 219724.
+
+2015-01-16 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+ Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+
+ PR target/64263
+ * config/aarch64/aarch64.md (*movsi_aarch64): Don't split if the
+ destination is not a GP reg.
+ (*movdi_aarch64): Likewise.
+
+2015-01-16 David Edelsohn <dje.gcc@gmail.com>
+
+ PR target/64623
+ * config/rs6000/default64.h: Revert ISA change.
+
+2015-01-16 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/64614
+ * tree-ssa-uninit.c: Include tree-cfg.h.
+ (MAX_SWITCH_CASES): New define.
+ (convert_control_dep_chain_into_preds): Handle switch statements.
+ (is_pred_expr_subset_of): Handle x == CST vs. (x & CST) != 0.
+ (normalize_one_pred_1): Do not split bit-manipulations.
+ Record (x & CST).
+
+2015-01-16 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/64568
+ * tree-ssa-forwprop.c (pass_forwprop::execute): Guard
+ complex load rewriting for TARGET_MEM_REFs.
+
+2015-01-16 Uros Bizjak <ubizjak@gmail.com>
+
+ * builtins.c (expand_builtin_acc_on_device): Check target for NULL.
+
+2015-01-16 Matthew Wahab <matthew.wahab@arm.com>
+
+ PR target/64149
+ * config/aarch64/aarch64.opt: Remove lra option and aarch64_lra_flag
+ variable.
+ * config/aarch64/aarch64.c (TARGET_LRA_P): Set to hook_bool_void_true.
+ (aarch64_lra_p): Remove.
+
+2015-01-16 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR target/64363
+ * ipa-chkp.h (chkp_instrumentable_p): New.
+ * ipa-chkp.c: Include tree-inline.h.
+ (chkp_instrumentable_p): New.
+ (chkp_maybe_create_clone): Use chkp_instrumentable_p.
+ Fix processing of not instrumentable functions.
+ (chkp_versioning): Use chkp_instrumentable_p. Warn about
+ not instrumentable functions.
+ * tree-chkp.c (chkp_add_bounds_to_call_stmt): Use
+ chkp_instrumentable_p.
+ * tree-inline.h (copy_forbidden): New.
+ * tree-inline.c (copy_forbidden): Not static anymore.
+
+2015-01-16 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * optc-save-gen.awk (cl_target_option_print_diff): Mark indent,
+ ptr1, ptr2 unused.
+
+2015-01-16 Robert Suchanek <robert.suchanek@imgtec.com>
+
+ * lra-constraints.c (curr_insn_transform): Change a reload pseudo of
+ type OP_OUT to OP_INOUT.
+
+2015-01-16 Robert Suchanek <robert.suchanek@imgtec.com>
+
+ * simplify-rtx.c (simplify_replace_fn_rtx): Simplify (lo_sum
+ (high x) y) to y if x and y have the same base.
+
+2015-01-16 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/arm/cortex-a57.md: New.
+ * config/aarch64/aarch64.md: Include it.
+ * config/aarch64/aarch64-cores.def (cortex-a57): Tune for it.
+ * config/aarch64/aarch64-tune.md: Regenerate.
+
+2015-01-16 Zhenqiang Chen <zhenqiang.chen@arm.com>
+
+ PR target/64015
+ * ccmp.c (expand_ccmp_next): New function.
+ (expand_ccmp_expr_1, expand_ccmp_expr): Handle operand insn sequence
+ and compare insn sequence.
+ * config/aarch64/aarch64.c (aarch64_code_to_ccmode,
+ aarch64_gen_ccmp_first, aarch64_gen_ccmp_next): New functions.
+ (TARGET_GEN_CCMP_FIRST, TARGET_GEN_CCMP_NEXT): New MICRO.
+ * config/aarch64/aarch64.md (*ccmp_and): Changed to ccmp_and<mode>.
+ (*ccmp_ior): Changed to ccmp_ior<mode>.
+ (cmp<mode>): New pattern.
+ * doc/tm.texi (TARGET_GEN_CCMP_FIRST, TARGET_GEN_CCMP_NEXT): Update
+ parameters.
+ * target.def (gen_ccmp_first, gen_ccmp_next): Update parameters.
+
+2015-01-16 Ilya Tocar <ilya.tocar@intel.com>
+
+ * config/i386/avx2intrin.h (_mm256_bslli_epi128,
+ _mm256_bsrli_epi128): New.
+ * config/i386/emmintrin.h (_mm_bsrli_si128, _mm_bslli_si128): Ditto.
+
+2015-01-15 Jiong Wang <jiong.wang@arm.com>
+
+ * expmed.c (store_bit_field_using_insv): Improve warning message.
+ Use %wu instead of HOST_WIDE_INT_PRINT_UNSIGNED.
+
+2015-01-15 Jiong Wang <jiong.wang@arm.com>
+
+ PR rtl-optimization/64011
+ * expmed.c (store_bit_field_using_insv): Warn and truncate bitsize when
+ there is partial overflow.
+
+2015-01-16 Chung-Ju Wu <jasonwucj@gmail.com>
+
+ * config/nds32/nds32-protos.h (nds32_expand_epilogue): Change
+ prototype.
+ (nds32_expand_epilogue_v3pop): Likewise.
+ * config/nds32/nds32.md (sibcall): Define this for sibling call
+ optimization.
+ (sibcall_register): Likewise.
+ (sibcall_immediate): Likewise.
+ (sibcall_value): Likewise.
+ (sibcall_value_register): Likewise.
+ (sibcall_value_immediate): Likewise.
+ (sibcall_epilogue): Likewise.
+ (epilogue): Pass false to indicate this is not a sibcall epilogue.
+ * config/nds32/nds32.c (nds32_expand_epilogue): Consider sibcall case.
+ (nds32_expand_epilogue_v3pop): Likewise.
+
+2015-01-16 Chung-Ju Wu <jasonwucj@gmail.com>
+
+ * config/nds32/nds32-protos.h (nds32_can_use_return_insn): New.
+ * config/nds32/nds32.md (unspec_volatile_func_return): Remove.
+ (return_internal): New.
+ (return): Define this named pattern.
+ (simple_return): Define this named pattern.
+ * config/nds32/nds32.c (nds32_expand_epilogue): Emit return_internal
+ pattern instead of unspec_volatile_func_return.
+ (nds32_expand_epilogue_v3pop): Likewise.
+ (nds32_can_use_return_insn): New function.
+
+2015-01-16 Chung-Ju Wu <jasonwucj@gmail.com>
+
+ * config/nds32/constants.md (UNSPEC_VOLATILE_POP25_RETURN): New.
+ * config/nds32/nds32.md (pop25return): New.
+ * config/nds32/nds32.c (nds32_expand_epilogue_v3pop): Emit
+ pop25return pattern.
+
+2015-01-16 Chung-Ju Wu <jasonwucj@gmail.com>
+
+ * doc/invoke.texi (NDS32 Options): Remove -mforce-fp-as-gp,
+ -mforbid-fp-as-gp, and -mex9 options.
+
+2015-01-16 Chung-Ju Wu <jasonwucj@gmail.com>
+
+ * doc/invoke.texi (NDS32 Options): Add -mcmodel= option and
+ remove -mgp-direct option.
+
+2015-01-15 Jan Hubicka <hubicka@ucw.cz>
+
+ * doc/invoke.texi (--param early-inlining-insns): Update default value.
+ * params.def (PARAM_EARLY_INLINING_INSNS): Set to 14.
+
+2015-01-15 Jan Hubicka <hubicka@ucw.cz>
+
+ * ipa-inline.c (inline_small_functions): Work around hints
+ cache issue.
+
2015-01-15 Sandra Loosemore <sandra@codesourcery.com>
PR target/59710
@@ -276,7 +477,7 @@
cfganal.h, cfgbuild.h, cfgcleanup.h, lcm.h, cfgloopmanip.h,
builtins.def, and chkp-builtins.def.
-2014-01-15 David Edelsohn <dje.gcc@gmail.com>
+2015-01-15 David Edelsohn <dje.gcc@gmail.com>
* config/rs6000/default64.h (TARGET_DEFAULT) [LITTLE_ENDIAN]: Use
ISA 2.7 (POWER8).
@@ -978,7 +1179,7 @@
Do not save lr in case of tail call.
* config/arm/thumb2.md (*thumb2_pop_single): New pattern.
-2015-01-13 Martin Uecker <uecker@eecs.berkeley.edu>
+2015-01-14 Martin Uecker <uecker@eecs.berkeley.edu>
* tree-vrp.c (check_array_ref): Emit more warnings
for warn_array_bounds >= 2.
@@ -1116,7 +1317,7 @@
(perform_symbolic_merge): This. Also fix computation of the range and
end of the symbolic number corresponding to the result of a bitwise OR.
-2014-01-13 Richard Biener <rguenther@suse.de>
+2015-01-13 Richard Biener <rguenther@suse.de>
PR tree-optimization/64568
* tree-ssa-forwprop.c (pass_forwprop::execute): Properly
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 477e39b..369f65c 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -6,7 +6,7 @@
* *
* C Implementation File *
* *
- * Copyright (C) 1992-2014, Free Software Foundation, Inc. *
+ * Copyright (C) 1992-2015, Free Software Foundation, Inc. *
* *
* GNAT is free software; you can redistribute it and/or modify it under *
* terms of the GNU General Public License as published by the Free Soft- *
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 9a6a11b..bf5acbc 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -5930,7 +5930,7 @@ expand_builtin_acc_on_device (tree exp, rtx target)
v2 = GEN_INT (GOMP_DEVICE_HOST);
#endif
machine_mode target_mode = TYPE_MODE (integer_type_node);
- if (!REG_P (target) || GET_MODE (target) != target_mode)
+ if (!target || !register_operand (target, target_mode))
target = gen_reg_rtx (target_mode);
emit_move_insn (target, const1_rtx);
rtx_code_label *done_label = gen_label_rtx ();
diff --git a/gcc/ccmp.c b/gcc/ccmp.c
index 1130329..903d5a8 100644
--- a/gcc/ccmp.c
+++ b/gcc/ccmp.c
@@ -92,7 +92,16 @@ along with GCC; see the file COPYING3. If not see
* If the final result is not used in a COND_EXPR (checked by function
used_in_cond_stmt_p), it calls cstorecc4 pattern to store the CC to a
- general register. */
+ general register.
+
+ Since the operands of the later compares might clobber CC reg, we do not
+ emit the insns during expand. We keep the insn sequences in two seq
+
+ * prep_seq, which includes all the insns to prepare the operands.
+ * gen_seq, which includes all the compare and conditional compares.
+
+ If all checks OK in expand_ccmp_expr, it emits insns in prep_seq, then
+ insns in gen_seq. */
/* Check whether G is a potential conditional compare candidate. */
static bool
@@ -172,6 +181,27 @@ used_in_cond_stmt_p (tree exp)
return expand_cond;
}
+/* PREV is the CC flag from precvious compares. The function expands the
+ next compare based on G which ops previous compare with CODE.
+ PREP_SEQ returns all insns to prepare opearands for compare.
+ GEN_SEQ returnss all compare insns. */
+static rtx
+expand_ccmp_next (gimple g, enum tree_code code, rtx prev,
+ rtx *prep_seq, rtx *gen_seq)
+{
+ enum rtx_code rcode;
+ int unsignedp = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (g)));
+
+ gcc_assert (code == BIT_AND_EXPR || code == BIT_IOR_EXPR);
+
+ rcode = get_rtx_code (gimple_assign_rhs_code (g), unsignedp);
+
+ return targetm.gen_ccmp_next (prep_seq, gen_seq, prev, rcode,
+ gimple_assign_rhs1 (g),
+ gimple_assign_rhs2 (g),
+ get_rtx_code (code, 0));
+}
+
/* Expand conditional compare gimple G. A typical CCMP sequence is like:
CC0 = CMP (a, b);
@@ -180,9 +210,11 @@ used_in_cond_stmt_p (tree exp)
CCn = CCMP (NE (CCn-1, 0), CMP (...));
hook gen_ccmp_first is used to expand the first compare.
- hook gen_ccmp_next is used to expand the following CCMP. */
+ hook gen_ccmp_next is used to expand the following CCMP.
+ PREP_SEQ returns all insns to prepare opearand.
+ GEN_SEQ returns all compare insns. */
static rtx
-expand_ccmp_expr_1 (gimple g)
+expand_ccmp_expr_1 (gimple g, rtx *prep_seq, rtx *gen_seq)
{
tree exp = gimple_assign_rhs_to_tree (g);
enum tree_code code = TREE_CODE (exp);
@@ -199,52 +231,27 @@ expand_ccmp_expr_1 (gimple g)
{
if (TREE_CODE_CLASS (code1) == tcc_comparison)
{
- int unsignedp0, unsignedp1;
- enum rtx_code rcode0, rcode1;
- rtx op0, op1, op2, op3, tmp;
+ int unsignedp0;
+ enum rtx_code rcode0;
unsignedp0 = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (gs0)));
rcode0 = get_rtx_code (code0, unsignedp0);
- unsignedp1 = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (gs1)));
- rcode1 = get_rtx_code (code1, unsignedp1);
-
- expand_operands (gimple_assign_rhs1 (gs0),
- gimple_assign_rhs2 (gs0),
- NULL_RTX, &op0, &op1, EXPAND_NORMAL);
-
- /* Since the operands of GS1 might clobber CC reg, we expand the
- operands of GS1 before GEN_CCMP_FIRST. */
- expand_operands (gimple_assign_rhs1 (gs1),
- gimple_assign_rhs2 (gs1),
- NULL_RTX, &op2, &op3, EXPAND_NORMAL);
- tmp = targetm.gen_ccmp_first (rcode0, op0, op1);
+
+ tmp = targetm.gen_ccmp_first (prep_seq, gen_seq, rcode0,
+ gimple_assign_rhs1 (gs0),
+ gimple_assign_rhs2 (gs0));
if (!tmp)
return NULL_RTX;
- return targetm.gen_ccmp_next (tmp, rcode1, op2, op3,
- get_rtx_code (code, 0));
+ return expand_ccmp_next (gs1, code, tmp, prep_seq, gen_seq);
}
else
{
- rtx op0, op1;
- enum rtx_code rcode;
- int unsignedp = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (gs0)));
-
- rcode = get_rtx_code (gimple_assign_rhs_code (gs0), unsignedp);
-
- /* Hoist the preparation operations above the entire
- conditional compare sequence. */
- expand_operands (gimple_assign_rhs1 (gs0),
- gimple_assign_rhs2 (gs0),
- NULL_RTX, &op0, &op1, EXPAND_NORMAL);
-
- gcc_assert (code1 == BIT_AND_EXPR || code1 == BIT_IOR_EXPR);
+ tmp = expand_ccmp_expr_1 (gs1, prep_seq, gen_seq);
+ if (!tmp)
+ return NULL_RTX;
- /* Note: We swap the order to make the recursive function work. */
- tmp = expand_ccmp_expr_1 (gs1);
- if (tmp)
- return targetm.gen_ccmp_next (tmp, rcode, op0, op1,
- get_rtx_code (code, 0));
+ return expand_ccmp_next (gs0, code, tmp, prep_seq, gen_seq);
}
}
else
@@ -254,21 +261,11 @@ expand_ccmp_expr_1 (gimple g)
if (TREE_CODE_CLASS (gimple_assign_rhs_code (gs1)) == tcc_comparison)
{
- rtx op0, op1;
- enum rtx_code rcode;
- int unsignedp = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (gs1)));
-
- rcode = get_rtx_code (gimple_assign_rhs_code (gs1), unsignedp);
-
- /* Hoist the preparation operations above the entire
- conditional compare sequence. */
- expand_operands (gimple_assign_rhs1 (gs1),
- gimple_assign_rhs2 (gs1),
- NULL_RTX, &op0, &op1, EXPAND_NORMAL);
- tmp = expand_ccmp_expr_1 (gs0);
- if (tmp)
- return targetm.gen_ccmp_next (tmp, rcode, op0, op1,
- get_rtx_code (code, 0));
+ tmp = expand_ccmp_expr_1 (gs0, prep_seq, gen_seq);
+ if (!tmp)
+ return NULL_RTX;
+
+ return expand_ccmp_next (gs1, code, tmp, prep_seq, gen_seq);
}
else
{
@@ -288,23 +285,30 @@ expand_ccmp_expr (gimple g)
{
rtx_insn *last;
rtx tmp;
+ rtx prep_seq, gen_seq;
+
+ prep_seq = gen_seq = NULL_RTX;
if (!ccmp_candidate_p (g))
return NULL_RTX;
last = get_last_insn ();
- tmp = expand_ccmp_expr_1 (g);
+ tmp = expand_ccmp_expr_1 (g, &prep_seq, &gen_seq);
if (tmp)
{
enum insn_code icode;
enum machine_mode cc_mode = CCmode;
-
tree lhs = gimple_assign_lhs (g);
+
/* TMP should be CC. If it is used in a GIMPLE_COND, just return it.
Note: Target needs to define "cbranchcc4". */
if (used_in_cond_stmt_p (lhs))
- return tmp;
+ {
+ emit_insn (prep_seq);
+ emit_insn (gen_seq);
+ return tmp;
+ }
#ifdef SELECT_CC_MODE
cc_mode = SELECT_CC_MODE (NE, tmp, const0_rtx);
@@ -314,9 +318,12 @@ expand_ccmp_expr (gimple g)
icode = optab_handler (cstore_optab, cc_mode);
if (icode != CODE_FOR_nothing)
{
- tree lhs = gimple_assign_lhs (g);
enum machine_mode mode = TYPE_MODE (TREE_TYPE (lhs));
rtx target = gen_reg_rtx (mode);
+
+ emit_insn (prep_seq);
+ emit_insn (gen_seq);
+
tmp = emit_cstore (target, icode, NE, cc_mode, cc_mode,
0, tmp, const0_rtx, 1, mode);
if (tmp)
diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def
index 35a43e6..f978eb1 100644
--- a/gcc/config/aarch64/aarch64-cores.def
+++ b/gcc/config/aarch64/aarch64-cores.def
@@ -35,7 +35,7 @@
/* V8 Architecture Processors. */
AARCH64_CORE("cortex-a53", cortexa53, cortexa53, 8, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa53)
-AARCH64_CORE("cortex-a57", cortexa15, cortexa15, 8, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa57)
+AARCH64_CORE("cortex-a57", cortexa57, cortexa57, 8, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC, cortexa57)
AARCH64_CORE("thunderx", thunderx, thunderx, 8, AARCH64_FL_FOR_ARCH8 | AARCH64_FL_CRC | AARCH64_FL_CRYPTO, thunderx)
AARCH64_CORE("xgene1", xgene1, xgene1, 8, AARCH64_FL_FOR_ARCH8, xgene1)
diff --git a/gcc/config/aarch64/aarch64-tune.md b/gcc/config/aarch64/aarch64-tune.md
index 6409082..80f59c8 100644
--- a/gcc/config/aarch64/aarch64-tune.md
+++ b/gcc/config/aarch64/aarch64-tune.md
@@ -1,5 +1,5 @@
;; -*- buffer-read-only: t -*-
;; Generated automatically by gentune.sh from aarch64-cores.def
(define_attr "tune"
- "cortexa53,cortexa15,thunderx,xgene1,cortexa57cortexa53"
+ "cortexa53,cortexa57,thunderx,xgene1,cortexa57cortexa53"
(const (symbol_ref "((enum attr_tune) aarch64_tune)")))
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 34cce91..fdb0116 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -156,7 +156,6 @@ enum aarch64_code_model aarch64_cmodel;
#define TARGET_HAVE_TLS 1
#endif
-static bool aarch64_lra_p (void);
static bool aarch64_composite_type_p (const_tree, machine_mode);
static bool aarch64_vfp_is_call_or_return_candidate (machine_mode,
const_tree,
@@ -7810,13 +7809,6 @@ aapcs_vfp_sub_candidate (const_tree type, machine_mode *modep)
return -1;
}
-/* Return true if we use LRA instead of reload pass. */
-static bool
-aarch64_lra_p (void)
-{
- return aarch64_lra_flag;
-}
-
/* Return TRUE if the type, as described by TYPE and MODE, is a composite
type as described in AAPCS64 \S 4.3. This includes aggregate, union and
array types. The C99 floating-point complex types are also considered
@@ -10381,6 +10373,198 @@ aarch64_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
}
+static enum machine_mode
+aarch64_code_to_ccmode (enum rtx_code code)
+{
+ switch (code)
+ {
+ case NE:
+ return CC_DNEmode;
+
+ case EQ:
+ return CC_DEQmode;
+
+ case LE:
+ return CC_DLEmode;
+
+ case LT:
+ return CC_DLTmode;
+
+ case GE:
+ return CC_DGEmode;
+
+ case GT:
+ return CC_DGTmode;
+
+ case LEU:
+ return CC_DLEUmode;
+
+ case LTU:
+ return CC_DLTUmode;
+
+ case GEU:
+ return CC_DGEUmode;
+
+ case GTU:
+ return CC_DGTUmode;
+
+ default:
+ return CCmode;
+ }
+}
+
+static rtx
+aarch64_gen_ccmp_first (rtx *prep_seq, rtx *gen_seq,
+ int code, tree treeop0, tree treeop1)
+{
+ enum machine_mode op_mode, cmp_mode, cc_mode;
+ rtx op0, op1, cmp, target;
+ int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0));
+ enum insn_code icode;
+ struct expand_operand ops[4];
+
+ cc_mode = aarch64_code_to_ccmode ((enum rtx_code) code);
+ if (cc_mode == CCmode)
+ return NULL_RTX;
+
+ start_sequence ();
+ expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
+
+ op_mode = GET_MODE (op0);
+ if (op_mode == VOIDmode)
+ op_mode = GET_MODE (op1);
+
+ switch (op_mode)
+ {
+ case QImode:
+ case HImode:
+ case SImode:
+ cmp_mode = SImode;
+ icode = CODE_FOR_cmpsi;
+ break;
+
+ case DImode:
+ cmp_mode = DImode;
+ icode = CODE_FOR_cmpdi;
+ break;
+
+ default:
+ end_sequence ();
+ return NULL_RTX;
+ }
+
+ op0 = prepare_operand (icode, op0, 2, op_mode, cmp_mode, unsignedp);
+ op1 = prepare_operand (icode, op1, 3, op_mode, cmp_mode, unsignedp);
+ if (!op0 || !op1)
+ {
+ end_sequence ();
+ return NULL_RTX;
+ }
+ *prep_seq = get_insns ();
+ end_sequence ();
+
+ cmp = gen_rtx_fmt_ee ((enum rtx_code) code, cmp_mode, op0, op1);
+ target = gen_rtx_REG (CCmode, CC_REGNUM);
+
+ create_output_operand (&ops[0], target, CCmode);
+ create_fixed_operand (&ops[1], cmp);
+ create_fixed_operand (&ops[2], op0);
+ create_fixed_operand (&ops[3], op1);
+
+ start_sequence ();
+ if (!maybe_expand_insn (icode, 4, ops))
+ {
+ end_sequence ();
+ return NULL_RTX;
+ }
+ *gen_seq = get_insns ();
+ end_sequence ();
+
+ return gen_rtx_REG (cc_mode, CC_REGNUM);
+}
+
+static rtx
+aarch64_gen_ccmp_next (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code,
+ tree treeop0, tree treeop1, int bit_code)
+{
+ rtx op0, op1, cmp0, cmp1, target;
+ enum machine_mode op_mode, cmp_mode, cc_mode;
+ int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0));
+ enum insn_code icode = CODE_FOR_ccmp_andsi;
+ struct expand_operand ops[6];
+
+ cc_mode = aarch64_code_to_ccmode ((enum rtx_code) cmp_code);
+ if (cc_mode == CCmode)
+ return NULL_RTX;
+
+ push_to_sequence ((rtx_insn*) *prep_seq);
+ expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
+
+ op_mode = GET_MODE (op0);
+ if (op_mode == VOIDmode)
+ op_mode = GET_MODE (op1);
+
+ switch (op_mode)
+ {
+ case QImode:
+ case HImode:
+ case SImode:
+ cmp_mode = SImode;
+ icode = (enum rtx_code) bit_code == AND ? CODE_FOR_ccmp_andsi
+ : CODE_FOR_ccmp_iorsi;
+ break;
+
+ case DImode:
+ cmp_mode = DImode;
+ icode = (enum rtx_code) bit_code == AND ? CODE_FOR_ccmp_anddi
+ : CODE_FOR_ccmp_iordi;
+ break;
+
+ default:
+ end_sequence ();
+ return NULL_RTX;
+ }
+
+ op0 = prepare_operand (icode, op0, 2, op_mode, cmp_mode, unsignedp);
+ op1 = prepare_operand (icode, op1, 3, op_mode, cmp_mode, unsignedp);
+ if (!op0 || !op1)
+ {
+ end_sequence ();
+ return NULL_RTX;
+ }
+ *prep_seq = get_insns ();
+ end_sequence ();
+
+ target = gen_rtx_REG (cc_mode, CC_REGNUM);
+ cmp1 = gen_rtx_fmt_ee ((enum rtx_code) cmp_code, cmp_mode, op0, op1);
+ cmp0 = gen_rtx_fmt_ee (NE, cmp_mode, prev, const0_rtx);
+
+ create_fixed_operand (&ops[0], prev);
+ create_fixed_operand (&ops[1], target);
+ create_fixed_operand (&ops[2], op0);
+ create_fixed_operand (&ops[3], op1);
+ create_fixed_operand (&ops[4], cmp0);
+ create_fixed_operand (&ops[5], cmp1);
+
+ push_to_sequence ((rtx_insn*) *gen_seq);
+ if (!maybe_expand_insn (icode, 6, ops))
+ {
+ end_sequence ();
+ return NULL_RTX;
+ }
+
+ *gen_seq = get_insns ();
+ end_sequence ();
+
+ return target;
+}
+
+#undef TARGET_GEN_CCMP_FIRST
+#define TARGET_GEN_CCMP_FIRST aarch64_gen_ccmp_first
+
+#undef TARGET_GEN_CCMP_NEXT
+#define TARGET_GEN_CCMP_NEXT aarch64_gen_ccmp_next
+
/* Implement TARGET_SCHED_MACRO_FUSION_P. Return true if target supports
instruction fusion of some sort. */
@@ -11140,7 +11324,7 @@ aarch64_gen_adjusted_ldpstp (rtx *operands, bool load,
#define TARGET_LIBGCC_CMP_RETURN_MODE aarch64_libgcc_cmp_return_mode
#undef TARGET_LRA_P
-#define TARGET_LRA_P aarch64_lra_p
+#define TARGET_LRA_P hook_bool_void_true
#undef TARGET_MANGLE_TYPE
#define TARGET_MANGLE_TYPE aarch64_mangle_type
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index adfa46d..fde5e4f 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -188,7 +188,7 @@
;; Scheduling
(include "../arm/cortex-a53.md")
-(include "../arm/cortex-a15.md")
+(include "../arm/cortex-a57.md")
(include "thunderx.md")
(include "../arm/xgene1.md")
@@ -248,7 +248,7 @@
""
"")
-(define_insn "*ccmp_and"
+(define_insn "ccmp_and<mode>"
[(set (match_operand 1 "ccmp_cc_register" "")
(compare
(and:SI
@@ -267,7 +267,7 @@
[(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
)
-(define_insn "*ccmp_ior"
+(define_insn "ccmp_ior<mode>"
[(set (match_operand 1 "ccmp_cc_register" "")
(compare
(ior:SI
@@ -286,6 +286,20 @@
[(set_attr "type" "alus_sreg,alus_imm,alus_imm")]
)
+(define_expand "cmp<mode>"
+ [(set (match_operand 0 "cc_register" "")
+ (match_operator:CC 1 "aarch64_comparison_operator"
+ [(match_operand:GPI 2 "register_operand" "")
+ (match_operand:GPI 3 "aarch64_plus_operand" "")]))]
+ ""
+ {
+ operands[1] = gen_rtx_fmt_ee (COMPARE,
+ SELECT_CC_MODE (GET_CODE (operands[1]),
+ operands[2], operands[3]),
+ operands[2], operands[3]);
+ }
+)
+
(define_insn "*condjump"
[(set (pc) (if_then_else (match_operator 0 "aarch64_comparison_operator"
[(match_operand 1 "cc_register" "") (const_int 0)])
@@ -845,7 +859,8 @@
fmov\\t%s0, %w1
fmov\\t%w0, %s1
fmov\\t%s0, %s1"
- "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), SImode)"
+ "CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), SImode)
+ && GP_REGNUM_P (REGNO (operands[0]))"
[(const_int 0)]
"{
aarch64_expand_mov_immediate (operands[0], operands[1]);
@@ -877,7 +892,8 @@
fmov\\t%x0, %d1
fmov\\t%d0, %d1
movi\\t%d0, %1"
- "(CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), DImode))"
+ "(CONST_INT_P (operands[1]) && !aarch64_move_imm (INTVAL (operands[1]), DImode))
+ && GP_REGNUM_P (REGNO (operands[0]))"
[(const_int 0)]
"{
aarch64_expand_mov_immediate (operands[0], operands[1]);
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
index 44c6350..f2ef124 100644
--- a/gcc/config/aarch64/aarch64.opt
+++ b/gcc/config/aarch64/aarch64.opt
@@ -107,10 +107,6 @@ mabi=
Target RejectNegative Joined Enum(aarch64_abi) Var(aarch64_abi) Init(AARCH64_ABI_DEFAULT)
-mabi=ABI Generate code that conforms to the specified ABI
-mlra
-Target Report Var(aarch64_lra_flag) Init(1) Save
-Use LRA instead of reload (transitional)
-
Enum
Name(aarch64_abi) Type(int)
Known AArch64 ABIs (for use with the -mabi= option):
diff --git a/gcc/config/arm/cortex-a57.md b/gcc/config/arm/cortex-a57.md
new file mode 100644
index 0000000..c9782f2
--- /dev/null
+++ b/gcc/config/arm/cortex-a57.md
@@ -0,0 +1,797 @@
+;; ARM Cortex-A57 pipeline description
+;; Copyright (C) 2014-2015 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; GCC is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_automaton "cortex_a57")
+
+(define_attr "cortex_a57_neon_type"
+ "neon_abd, neon_abd_q, neon_arith_acc, neon_arith_acc_q,
+ neon_arith_basic, neon_arith_complex,
+ neon_reduc_add_acc, neon_multiply, neon_multiply_q,
+ neon_multiply_long, neon_mla, neon_mla_q, neon_mla_long,
+ neon_sat_mla_long, neon_shift_acc, neon_shift_imm_basic,
+ neon_shift_imm_complex,
+ neon_shift_reg_basic, neon_shift_reg_basic_q, neon_shift_reg_complex,
+ neon_shift_reg_complex_q, neon_fp_negabs, neon_fp_arith,
+ neon_fp_arith_q, neon_fp_reductions_q, neon_fp_cvt_int,
+ neon_fp_cvt_int_q, neon_fp_cvt16, neon_fp_minmax, neon_fp_mul,
+ neon_fp_mul_q, neon_fp_mla, neon_fp_mla_q, neon_fp_recpe_rsqrte,
+ neon_fp_recpe_rsqrte_q, neon_fp_recps_rsqrts, neon_fp_recps_rsqrts_q,
+ neon_bitops, neon_bitops_q, neon_from_gp,
+ neon_from_gp_q, neon_move, neon_tbl3_tbl4, neon_zip_q, neon_to_gp,
+ neon_load_a, neon_load_b, neon_load_c, neon_load_d, neon_load_e,
+ neon_load_f, neon_store_a, neon_store_b, neon_store_complex,
+ unknown"
+ (cond [
+ (eq_attr "type" "neon_abd, neon_abd_long")
+ (const_string "neon_abd")
+ (eq_attr "type" "neon_abd_q")
+ (const_string "neon_abd_q")
+ (eq_attr "type" "neon_arith_acc, neon_reduc_add_acc,\
+ neon_reduc_add_acc_q")
+ (const_string "neon_arith_acc")
+ (eq_attr "type" "neon_arith_acc_q")
+ (const_string "neon_arith_acc_q")
+ (eq_attr "type" "neon_add, neon_add_q, neon_add_long,\
+ neon_add_widen, neon_neg, neon_neg_q,\
+ neon_reduc_add, neon_reduc_add_q,\
+ neon_reduc_add_long, neon_sub, neon_sub_q,\
+ neon_sub_long, neon_sub_widen, neon_logic,\
+ neon_logic_q, neon_tst, neon_tst_q")
+ (const_string "neon_arith_basic")
+ (eq_attr "type" "neon_abs, neon_abs_q, neon_add_halve_narrow_q,\
+ neon_add_halve, neon_add_halve_q,\
+ neon_sub_halve, neon_sub_halve_q, neon_qabs,\
+ neon_qabs_q, neon_qadd, neon_qadd_q, neon_qneg,\
+ neon_qneg_q, neon_qsub, neon_qsub_q,\
+ neon_sub_halve_narrow_q,\
+ neon_compare, neon_compare_q,\
+ neon_compare_zero, neon_compare_zero_q,\
+ neon_minmax, neon_minmax_q, neon_reduc_minmax,\
+ neon_reduc_minmax_q")
+ (const_string "neon_arith_complex")
+
+ (eq_attr "type" "neon_mul_b, neon_mul_h, neon_mul_s,\
+ neon_mul_h_scalar, neon_mul_s_scalar,\
+ neon_sat_mul_b, neon_sat_mul_h,\
+ neon_sat_mul_s, neon_sat_mul_h_scalar,\
+ neon_sat_mul_s_scalar,\
+ neon_mul_b_long, neon_mul_h_long,\
+ neon_mul_s_long, neon_mul_d_long,\
+ neon_mul_h_scalar_long, neon_mul_s_scalar_long,\
+ neon_sat_mul_b_long, neon_sat_mul_h_long,\
+ neon_sat_mul_s_long, neon_sat_mul_h_scalar_long,\
+ neon_sat_mul_s_scalar_long")
+ (const_string "neon_multiply")
+ (eq_attr "type" "neon_mul_b_q, neon_mul_h_q, neon_mul_s_q,\
+ neon_mul_h_scalar_q, neon_mul_s_scalar_q,\
+ neon_sat_mul_b_q, neon_sat_mul_h_q,\
+ neon_sat_mul_s_q, neon_sat_mul_h_scalar_q,\
+ neon_sat_mul_s_scalar_q")
+ (const_string "neon_multiply_q")
+ (eq_attr "type" "neon_mla_b, neon_mla_h, neon_mla_s,\
+ neon_mla_h_scalar, neon_mla_s_scalar,\
+ neon_mla_b_long, neon_mla_h_long,\
+ neon_mla_s_long,\
+ neon_mla_h_scalar_long, neon_mla_s_scalar_long")
+ (const_string "neon_mla")
+ (eq_attr "type" "neon_mla_b_q, neon_mla_h_q, neon_mla_s_q,\
+ neon_mla_h_scalar_q, neon_mla_s_scalar_q")
+ (const_string "neon_mla_q")
+ (eq_attr "type" "neon_sat_mla_b_long, neon_sat_mla_h_long,\
+ neon_sat_mla_s_long, neon_sat_mla_h_scalar_long,\
+ neon_sat_mla_s_scalar_long")
+ (const_string "neon_sat_mla_long")
+
+ (eq_attr "type" "neon_shift_acc, neon_shift_acc_q")
+ (const_string "neon_shift_acc")
+ (eq_attr "type" "neon_shift_imm, neon_shift_imm_q,\
+ neon_shift_imm_narrow_q, neon_shift_imm_long")
+ (const_string "neon_shift_imm_basic")
+ (eq_attr "type" "neon_sat_shift_imm, neon_sat_shift_imm_q,\
+ neon_sat_shift_imm_narrow_q")
+ (const_string "neon_shift_imm_complex")
+ (eq_attr "type" "neon_shift_reg")
+ (const_string "neon_shift_reg_basic")
+ (eq_attr "type" "neon_shift_reg_q")
+ (const_string "neon_shift_reg_basic_q")
+ (eq_attr "type" "neon_sat_shift_reg")
+ (const_string "neon_shift_reg_complex")
+ (eq_attr "type" "neon_sat_shift_reg_q")
+ (const_string "neon_shift_reg_complex_q")
+
+ (eq_attr "type" "neon_fp_neg_s, neon_fp_neg_s_q,\
+ neon_fp_abs_s, neon_fp_abs_s_q,\
+ neon_fp_neg_d, neon_fp_neg_d_q,\
+ neon_fp_abs_d, neon_fp_abs_d_q")
+ (const_string "neon_fp_negabs")
+ (eq_attr "type" "neon_fp_addsub_s, neon_fp_abd_s,\
+ neon_fp_reduc_add_s, neon_fp_compare_s,\
+ neon_fp_minmax_s, neon_fp_round_s,\
+ neon_fp_addsub_d, neon_fp_abd_d,\
+ neon_fp_reduc_add_d, neon_fp_compare_d,\
+ neon_fp_minmax_d, neon_fp_round_d,\
+ neon_fp_reduc_minmax_s, neon_fp_reduc_minmax_d")
+ (const_string "neon_fp_arith")
+ (eq_attr "type" "neon_fp_addsub_s_q, neon_fp_abd_s_q,\
+ neon_fp_reduc_add_s_q, neon_fp_compare_s_q,\
+ neon_fp_minmax_s_q, neon_fp_round_s_q,\
+ neon_fp_addsub_d_q, neon_fp_abd_d_q,\
+ neon_fp_reduc_add_d_q, neon_fp_compare_d_q,\
+ neon_fp_minmax_d_q, neon_fp_round_d_q")
+ (const_string "neon_fp_arith_q")
+ (eq_attr "type" "neon_fp_reduc_minmax_s_q,\
+ neon_fp_reduc_minmax_d_q,\
+ neon_fp_reduc_add_s_q, neon_fp_reduc_add_d_q")
+ (const_string "neon_fp_reductions_q")
+ (eq_attr "type" "neon_fp_to_int_s, neon_int_to_fp_s,\
+ neon_fp_to_int_d, neon_int_to_fp_d")
+ (const_string "neon_fp_cvt_int")
+ (eq_attr "type" "neon_fp_to_int_s_q, neon_int_to_fp_s_q,\
+ neon_fp_to_int_d_q, neon_int_to_fp_d_q")
+ (const_string "neon_fp_cvt_int_q")
+ (eq_attr "type" "neon_fp_cvt_narrow_s_q, neon_fp_cvt_widen_h")
+ (const_string "neon_fp_cvt16")
+ (eq_attr "type" "neon_fp_mul_s, neon_fp_mul_s_scalar,\
+ neon_fp_mul_d")
+ (const_string "neon_fp_mul")
+ (eq_attr "type" "neon_fp_mul_s_q, neon_fp_mul_s_scalar_q,\
+ neon_fp_mul_d_q, neon_fp_mul_d_scalar_q")
+ (const_string "neon_fp_mul_q")
+ (eq_attr "type" "neon_fp_mla_s, neon_fp_mla_s_scalar,\
+ neon_fp_mla_d")
+ (const_string "neon_fp_mla")
+ (eq_attr "type" "neon_fp_mla_s_q, neon_fp_mla_s_scalar_q,
+ neon_fp_mla_d_q, neon_fp_mla_d_scalar_q")
+ (const_string "neon_fp_mla_q")
+ (eq_attr "type" "neon_fp_recpe_s, neon_fp_rsqrte_s,\
+ neon_fp_recpx_s,\
+ neon_fp_recpe_d, neon_fp_rsqrte_d,\
+ neon_fp_recpx_d")
+ (const_string "neon_fp_recpe_rsqrte")
+ (eq_attr "type" "neon_fp_recpe_s_q, neon_fp_rsqrte_s_q,\
+ neon_fp_recpx_s_q,\
+ neon_fp_recpe_d_q, neon_fp_rsqrte_d_q,\
+ neon_fp_recpx_d_q")
+ (const_string "neon_fp_recpe_rsqrte_q")
+ (eq_attr "type" "neon_fp_recps_s, neon_fp_rsqrts_s,\
+ neon_fp_recps_d, neon_fp_rsqrts_d")
+ (const_string "neon_fp_recps_rsqrts")
+ (eq_attr "type" "neon_fp_recps_s_q, neon_fp_rsqrts_s_q,\
+ neon_fp_recps_d_q, neon_fp_rsqrts_d_q")
+ (const_string "neon_fp_recps_rsqrts_q")
+ (eq_attr "type" "neon_bsl, neon_cls, neon_cnt,\
+ neon_rev, neon_permute, neon_rbit,\
+ neon_tbl1, neon_tbl2, neon_zip,\
+ neon_dup, neon_dup_q, neon_ext, neon_ext_q,\
+ neon_move, neon_move_q, neon_move_narrow_q")
+ (const_string "neon_bitops")
+ (eq_attr "type" "neon_bsl_q, neon_cls_q, neon_cnt_q,\
+ neon_rev_q, neon_permute_q, neon_rbit_q")
+ (const_string "neon_bitops_q")
+ (eq_attr "type" "neon_from_gp,f_mcr,f_mcrr")
+ (const_string "neon_from_gp")
+ (eq_attr "type" "neon_from_gp_q")
+ (const_string "neon_from_gp_q")
+ (eq_attr "type" "neon_tbl3, neon_tbl4")
+ (const_string "neon_tbl3_tbl4")
+ (eq_attr "type" "neon_zip_q")
+ (const_string "neon_zip_q")
+ (eq_attr "type" "neon_to_gp, neon_to_gp_q,f_mrc,f_mrrc")
+ (const_string "neon_to_gp")
+
+ (eq_attr "type" "f_loads, f_loadd,\
+ neon_load1_1reg, neon_load1_1reg_q,\
+ neon_load1_2reg, neon_load1_2reg_q")
+ (const_string "neon_load_a")
+ (eq_attr "type" "neon_load1_3reg, neon_load1_3reg_q,\
+ neon_load1_4reg, neon_load1_4reg_q")
+ (const_string "neon_load_b")
+ (eq_attr "type" "neon_load1_one_lane, neon_load1_one_lane_q,\
+ neon_load1_all_lanes, neon_load1_all_lanes_q,\
+ neon_load2_2reg, neon_load2_2reg_q,\
+ neon_load2_all_lanes, neon_load2_all_lanes_q")
+ (const_string "neon_load_c")
+ (eq_attr "type" "neon_load2_4reg, neon_load2_4reg_q,\
+ neon_load3_3reg, neon_load3_3reg_q,\
+ neon_load3_one_lane, neon_load3_one_lane_q,\
+ neon_load4_4reg, neon_load4_4reg_q")
+ (const_string "neon_load_d")
+ (eq_attr "type" "neon_load2_one_lane, neon_load2_one_lane_q,\
+ neon_load3_all_lanes, neon_load3_all_lanes_q,\
+ neon_load4_all_lanes, neon_load4_all_lanes_q")
+ (const_string "neon_load_e")
+ (eq_attr "type" "neon_load4_one_lane, neon_load4_one_lane_q")
+ (const_string "neon_load_f")
+
+ (eq_attr "type" "f_stores, f_stored,\
+ neon_store1_1reg")
+ (const_string "neon_store_a")
+ (eq_attr "type" "neon_store1_2reg, neon_store1_1reg_q")
+ (const_string "neon_store_b")
+ (eq_attr "type" "neon_store1_3reg, neon_store1_3reg_q,\
+ neon_store3_3reg, neon_store3_3reg_q,\
+ neon_store2_4reg, neon_store2_4reg_q,\
+ neon_store4_4reg, neon_store4_4reg_q,\
+ neon_store2_2reg, neon_store2_2reg_q,\
+ neon_store3_one_lane, neon_store3_one_lane_q,\
+ neon_store4_one_lane, neon_store4_one_lane_q,\
+ neon_store1_4reg, neon_store1_4reg_q,\
+ neon_store1_one_lane, neon_store1_one_lane_q,\
+ neon_store2_one_lane, neon_store2_one_lane_q")
+ (const_string "neon_store_complex")]
+ (const_string "unknown")))
+
+;; The Cortex-A57 core is modelled as a triple issue pipeline that has
+;; the following functional units.
+;; 1. Two pipelines for integer operations: SX1, SX2
+
+(define_cpu_unit "ca57_sx1_issue" "cortex_a57")
+(define_reservation "ca57_sx1" "ca57_sx1_issue")
+
+(define_cpu_unit "ca57_sx2_issue" "cortex_a57")
+(define_reservation "ca57_sx2" "ca57_sx2_issue")
+
+;; 2. One pipeline for complex integer operations: MX
+
+(define_cpu_unit "ca57_mx_issue"
+ "cortex_a57")
+(define_reservation "ca57_mx" "ca57_mx_issue")
+(define_reservation "ca57_mx_block" "ca57_mx_issue")
+
+;; 3. Two asymmetric pipelines for Neon and FP operations: CX1, CX2
+(define_automaton "cortex_a57_cx")
+
+(define_cpu_unit "ca57_cx1_issue"
+ "cortex_a57_cx")
+(define_cpu_unit "ca57_cx2_issue"
+ "cortex_a57_cx")
+
+(define_reservation "ca57_cx1" "ca57_cx1_issue")
+
+(define_reservation "ca57_cx2" "ca57_cx2_issue")
+(define_reservation "ca57_cx2_block" "ca57_cx2_issue*2")
+
+;; 4. One pipeline for branch operations: BX
+
+(define_cpu_unit "ca57_bx_issue" "cortex_a57")
+(define_reservation "ca57_bx" "ca57_bx_issue")
+
+;; 5. Two pipelines for load and store operations: LS1, LS2. The most
+;; valuable thing we can do is force a structural hazard to split
+;; up loads/stores.
+
+(define_cpu_unit "ca57_ls_issue" "cortex_a57")
+(define_cpu_unit "ca57_ldr, ca57_str" "cortex_a57")
+(define_reservation "ca57_load_model" "ca57_ls_issue,ca57_ldr*2")
+(define_reservation "ca57_store_model" "ca57_ls_issue,ca57_str")
+
+;; Block all issue queues.
+
+(define_reservation "ca57_block" "ca57_cx1_issue + ca57_cx2_issue
+ + ca57_mx_issue + ca57_sx1_issue
+ + ca57_sx2_issue + ca57_ls_issue")
+
+;; Simple Execution Unit:
+;;
+;; Simple ALU without shift
+(define_insn_reservation "cortex_a57_alu" 2
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\
+ alu_sreg,alus_sreg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,clz,rbit,rev,alu_dsp_reg,\
+ shift_imm,shift_reg,\
+ mov_imm,mov_reg,\
+ mvn_imm,mvn_reg,\
+ mrs,multiple,no_insn"))
+ "ca57_sx1|ca57_sx2")
+
+;; ALU ops with immediate shift
+(define_insn_reservation "cortex_a57_alu_shift" 3
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "extend,\
+ alu_shift_imm,alus_shift_imm,\
+ crc,logic_shift_imm,logics_shift_imm,\
+ mov_shift,mvn_shift"))
+ "ca57_mx")
+
+;; Multi-Cycle Execution Unit:
+;;
+;; ALU ops with register controlled shift
+(define_insn_reservation "cortex_a57_alu_shift_reg" 3
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg,\
+ mov_shift_reg,mvn_shift_reg"))
+ "ca57_mx")
+
+;; All multiplies
+;; TODO: AArch32 and AArch64 have different behaviour
+(define_insn_reservation "cortex_a57_mult32" 3
+ (and (eq_attr "tune" "cortexa57")
+ (ior (eq_attr "mul32" "yes")
+ (eq_attr "mul64" "yes")))
+ "ca57_mx")
+
+;; Integer divide
+(define_insn_reservation "cortex_a57_div" 10
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "udiv,sdiv"))
+ "ca57_mx_issue,ca57_mx_block*3")
+
+;; Block all issue pipes for a cycle
+(define_insn_reservation "cortex_a57_block" 1
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "block"))
+ "ca57_block")
+
+;; Branch execution Unit
+;;
+;; Branches take one issue slot.
+;; No latency as there is no result
+(define_insn_reservation "cortex_a57_branch" 0
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "branch"))
+ "ca57_bx")
+
+;; Load-store execution Unit
+;;
+;; Loads of up to two words.
+(define_insn_reservation "cortex_a57_load1" 5
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "load_byte,load1,load2"))
+ "ca57_load_model")
+
+;; Loads of three or four words.
+(define_insn_reservation "cortex_a57_load3" 5
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "load3,load4"))
+ "ca57_ls_issue*2,ca57_load_model")
+
+;; Stores of up to two words.
+(define_insn_reservation "cortex_a57_store1" 0
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "store1,store2"))
+ "ca57_store_model")
+
+;; Stores of three or four words.
+(define_insn_reservation "cortex_a57_store3" 0
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "store3,store4"))
+ "ca57_ls_issue*2,ca57_store_model")
+
+;; Advanced SIMD Unit - Integer Arithmetic Instructions.
+
+(define_insn_reservation "cortex_a57_neon_abd" 5
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_abd"))
+ "ca57_cx1|ca57_cx2")
+
+(define_insn_reservation "cortex_a57_neon_abd_q" 5
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_abd_q"))
+ "ca57_cx1+ca57_cx2")
+
+(define_insn_reservation "cortex_a57_neon_aba" 7
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_arith_acc"))
+ "ca57_cx2")
+
+(define_insn_reservation "cortex_a57_neon_aba_q" 8
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_arith_acc_q"))
+ "ca57_cx2+(ca57_cx2_issue,ca57_cx2)")
+
+(define_insn_reservation "cortex_a57_neon_arith_basic" 4
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_arith_basic"))
+ "ca57_cx1|ca57_cx2")
+
+(define_insn_reservation "cortex_a57_neon_arith_complex" 5
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_arith_complex"))
+ "ca57_cx1|ca57_cx2")
+
+;; Integer Multiply Instructions.
+
+(define_insn_reservation "cortex_a57_neon_multiply" 6
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_multiply"))
+ "ca57_cx1")
+
+(define_insn_reservation "cortex_a57_neon_multiply_q" 7
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_multiply_q"))
+ "ca57_cx1+(ca57_cx1_issue,ca57_cx1)")
+
+(define_insn_reservation "cortex_a57_neon_mla" 6
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_mla"))
+ "ca57_cx1")
+
+(define_insn_reservation "cortex_a57_neon_mla_q" 7
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_mla_q"))
+ "ca57_cx1+(ca57_cx1_issue,ca57_cx1)")
+
+(define_insn_reservation "cortex_a57_neon_sat_mla_long" 6
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_sat_mla_long"))
+ "ca57_cx1")
+
+;; Integer Shift Instructions.
+
+(define_insn_reservation
+ "cortex_a57_neon_shift_acc" 7
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_shift_acc"))
+ "ca57_cx2")
+
+(define_insn_reservation
+ "cortex_a57_neon_shift_imm_basic" 4
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_shift_imm_basic"))
+ "ca57_cx2")
+
+(define_insn_reservation
+ "cortex_a57_neon_shift_imm_complex" 5
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_shift_imm_complex"))
+ "ca57_cx2")
+
+(define_insn_reservation
+ "cortex_a57_neon_shift_reg_basic" 4
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_shift_reg_basic"))
+ "ca57_cx2")
+
+(define_insn_reservation
+ "cortex_a57_neon_shift_reg_basic_q" 5
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_shift_reg_basic_q"))
+ "ca57_cx2+(ca57_cx2_issue,ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_shift_reg_complex" 5
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_shift_reg_complex"))
+ "ca57_cx2")
+
+(define_insn_reservation
+ "cortex_a57_neon_shift_reg_complex_q" 6
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_shift_reg_complex_q"))
+ "ca57_cx2+(ca57_cx2_issue,ca57_cx2)")
+
+;; Floating Point Instructions.
+
+(define_insn_reservation
+ "cortex_a57_neon_fp_negabs" 4
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_fp_negabs"))
+ "(ca57_cx1|ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_fp_arith" 6
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_fp_arith"))
+ "(ca57_cx1|ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_fp_arith_q" 6
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_fp_arith_q"))
+ "(ca57_cx1+ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_fp_reductions_q" 10
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_fp_reductions_q"))
+ "(ca57_cx1+ca57_cx2),(ca57_cx1|ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_fp_cvt_int" 6
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_fp_cvt_int"))
+ "(ca57_cx1|ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_fp_cvt_int_q" 6
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_fp_cvt_int_q"))
+ "(ca57_cx1+ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_fp_cvt16" 10
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_fp_cvt16"))
+ "(ca57_cx1_issue+ca57_cx2_issue),(ca57_cx1|ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_fp_mul" 5
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_fp_mul"))
+ "(ca57_cx1|ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_fp_mul_q" 5
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_fp_mul_q"))
+ "(ca57_cx1+ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_fp_mla" 9
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_fp_mla"))
+ "(ca57_cx1,ca57_cx1)|(ca57_cx2,ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_fp_mla_q" 9
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_fp_mla_q"))
+ "(ca57_cx1+ca57_cx2),(ca57_cx1,ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_fp_recpe_rsqrte" 6
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_fp_recpe_rsqrte"))
+ "(ca57_cx1|ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_fp_recpe_rsqrte_q" 6
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_fp_recpe_rsqrte_q"))
+ "(ca57_cx1+ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_fp_recps_rsqrts" 10
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_fp_recps_rsqrts"))
+ "(ca57_cx1|ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_fp_recps_rsqrts_q" 10
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_fp_recps_rsqrts_q"))
+ "(ca57_cx1+ca57_cx2)")
+
+;; Miscellaneous Instructions.
+
+(define_insn_reservation
+ "cortex_a57_neon_bitops" 4
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_bitops"))
+ "(ca57_cx1|ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_bitops_q" 4
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_bitops_q"))
+ "(ca57_cx1+ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_from_gp" 9
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_from_gp"))
+ "(ca57_ls_issue+ca57_cx1_issue,ca57_cx1)
+ |(ca57_ls_issue+ca57_cx2_issue,ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_from_gp_q" 9
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_from_gp_q"))
+ "(ca57_ls_issue+ca57_cx1_issue,ca57_cx1)
+ +(ca57_ls_issue+ca57_cx2_issue,ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_tbl3_tbl4" 7
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_tbl3_tbl4"))
+ "(ca57_cx1_issue,ca57_cx1)
+ +(ca57_cx2_issue,ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_zip_q" 7
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_zip_q"))
+ "(ca57_cx1_issue,ca57_cx1)
+ +(ca57_cx2_issue,ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_to_gp" 7
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_to_gp"))
+ "((ca57_ls_issue+ca57_sx1_issue),ca57_sx1)
+ |((ca57_ls_issue+ca57_sx2_issue),ca57_sx2)")
+
+;; Load Instructions.
+
+(define_insn_reservation
+ "cortex_a57_neon_load_a" 6
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_load_a"))
+ "ca57_load_model")
+
+(define_insn_reservation
+ "cortex_a57_neon_load_b" 7
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_load_b"))
+ "ca57_ls_issue,ca57_ls_issue+ca57_ldr,ca57_ldr*2")
+
+(define_insn_reservation
+ "cortex_a57_neon_load_c" 9
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_load_c"))
+ "ca57_load_model+(ca57_cx1|ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_load_d" 11
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_load_d"))
+ "ca57_cx1_issue+ca57_cx2_issue,
+ ca57_ls_issue+ca57_ls_issue,ca57_ldr*2")
+
+(define_insn_reservation
+ "cortex_a57_neon_load_e" 9
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_load_e"))
+ "ca57_load_model+(ca57_cx1|ca57_cx2)")
+
+(define_insn_reservation
+ "cortex_a57_neon_load_f" 11
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_load_f"))
+ "ca57_cx1_issue+ca57_cx2_issue,
+ ca57_ls_issue+ca57_ls_issue,ca57_ldr*2")
+
+;; Store Instructions.
+
+(define_insn_reservation
+ "cortex_a57_neon_store_a" 0
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_store_a"))
+ "ca57_store_model")
+
+(define_insn_reservation
+ "cortex_a57_neon_store_b" 0
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_store_b"))
+ "ca57_store_model")
+
+;; These block issue for a number of cycles proportional to the number
+;; of 64-bit chunks they will store, we don't attempt to model that
+;; precisely, treat them as blocking execution for two cycles when
+;; issued.
+(define_insn_reservation
+ "cortex_a57_neon_store_complex" 0
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "cortex_a57_neon_type" "neon_store_complex"))
+ "ca57_block*2")
+
+;; Floating-Point Operations.
+
+(define_insn_reservation "cortex_a57_fp_const" 4
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "fconsts,fconstd"))
+ "(ca57_cx1|ca57_cx2)")
+
+(define_insn_reservation "cortex_a57_fp_add_sub" 6
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "fadds,faddd"))
+ "(ca57_cx1|ca57_cx2)")
+
+(define_insn_reservation "cortex_a57_fp_mul" 6
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "fmuls,fmuld"))
+ "(ca57_cx1|ca57_cx2)")
+
+(define_insn_reservation "cortex_a57_fp_mac" 10
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "fmacs,ffmas,fmacd,ffmad"))
+ "(ca57_cx1,nothing,nothing,ca57_cx1) \
+ |(ca57_cx2,nothing,nothing,ca57_cx2)")
+
+(define_insn_reservation "cortex_a57_fp_cvt" 6
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "f_cvt,f_cvtf2i,f_cvti2f"))
+ "(ca57_cx1|ca57_cx2)")
+
+(define_insn_reservation "cortex_a57_fp_cmp" 7
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "fcmps,fcmpd"))
+ "ca57_cx2")
+
+(define_insn_reservation "cortex_a57_fp_arith" 4
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "ffariths,ffarithd"))
+ "(ca57_cx1|ca57_cx2)")
+
+(define_insn_reservation "cortex_a57_fp_cpys" 4
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "fmov"))
+ "(ca57_cx1|ca57_cx2)")
+
+(define_insn_reservation "cortex_a57_fp_divs" 12
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "fdivs, fsqrts,\
+ neon_fp_div_s, neon_fp_sqrt_s"))
+ "ca57_cx2_block*5")
+
+(define_insn_reservation "cortex_a57_fp_divd" 16
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "fdivd, fsqrtd, neon_fp_div_d, neon_fp_sqrt_d"))
+ "ca57_cx2_block*3")
+
+(define_insn_reservation "cortex_a57_neon_fp_div_q" 20
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "fdivd, fsqrtd,\
+ neon_fp_div_s_q, neon_fp_div_d_q,\
+ neon_fp_sqrt_s_q, neon_fp_sqrt_d_q"))
+ "ca57_cx2_block*3")
+
+(define_insn_reservation "cortex_a57_crypto_simple" 4
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "crypto_aese,crypto_aesmc,crypto_sha1_fast"))
+ "ca57_cx2")
+
+(define_insn_reservation "cortex_a57_crypto_complex" 7
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "crypto_sha1_slow"))
+ "ca57_cx2+(ca57_cx2_issue,ca57_cx2)")
+
+(define_insn_reservation "cortex_a57_crypto_xor" 7
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "crypto_sha1_xor"))
+ "(ca57_cx1+ca57_cx2)")
+
+;; We lie with calls. They take up all issue slots, but are otherwise
+;; not harmful.
+(define_insn_reservation "cortex_a57_call" 1
+ (and (eq_attr "tune" "cortexa57")
+ (eq_attr "type" "call"))
+ "ca57_sx1_issue+ca57_sx2_issue+ca57_cx1_issue+ca57_cx2_issue\
+ +ca57_mx_issue+ca57_bx_issue+ca57_ls_issue"
+)
+
+;; Simple execution unit bypasses
+(define_bypass 1 "cortex_a57_alu"
+ "cortex_a57_alu,cortex_a57_alu_shift,cortex_a57_alu_shift_reg")
+(define_bypass 2 "cortex_a57_alu_shift"
+ "cortex_a57_alu,cortex_a57_alu_shift,cortex_a57_alu_shift_reg")
+(define_bypass 2 "cortex_a57_alu_shift_reg"
+ "cortex_a57_alu,cortex_a57_alu_shift,cortex_a57_alu_shift_reg")
+(define_bypass 1 "cortex_a57_alu" "cortex_a57_load1,cortex_a57_load3")
+(define_bypass 2 "cortex_a57_alu_shift" "cortex_a57_load1,cortex_a57_load3")
+(define_bypass 2 "cortex_a57_alu_shift_reg"
+ "cortex_a57_load1,cortex_a57_load3")
+
+;; An MLA or a MUL can feed a dependent MLA.
+(define_bypass 5 "cortex_a57_neon_*mla*,cortex_a57_neon_*mul*"
+ "cortex_a57_neon_*mla*")
+
+(define_bypass 5 "cortex_a57_fp_mul,cortex_a57_fp_mac"
+ "cortex_a57_fp_mac")
+
+;; We don't need to care about control hazards, either the branch is
+;; predicted in which case we pay no penalty, or the branch is
+;; mispredicted in which case instruction scheduling will be unlikely to
+;; help.
+(define_bypass 1 "cortex_a57_*"
+ "cortex_a57_call,cortex_a57_branch")
+
diff --git a/gcc/config/i386/avx2intrin.h b/gcc/config/i386/avx2intrin.h
index 669f1dc..b2a2f48 100644
--- a/gcc/config/i386/avx2intrin.h
+++ b/gcc/config/i386/avx2intrin.h
@@ -645,11 +645,20 @@ _mm256_sign_epi32 (__m256i __X, __m256i __Y)
#ifdef __OPTIMIZE__
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_bslli_epi128 (__m256i __A, const int __N)
+{
+ return (__m256i)__builtin_ia32_pslldqi256 (__A, __N * 8);
+}
+
+extern __inline __m256i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_slli_si256 (__m256i __A, const int __N)
{
return (__m256i)__builtin_ia32_pslldqi256 (__A, __N * 8);
}
#else
+#define _mm256_bslli_epi128(A, N) \
+ ((__m256i)__builtin_ia32_pslldqi256 ((__m256i)(A), (int)(N) * 8))
#define _mm256_slli_si256(A, N) \
((__m256i)__builtin_ia32_pslldqi256 ((__m256i)(A), (int)(N) * 8))
#endif
@@ -727,11 +736,20 @@ _mm256_sra_epi32 (__m256i __A, __m128i __B)
#ifdef __OPTIMIZE__
extern __inline __m256i
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_bsrli_epi128 (__m256i __A, const int __N)
+{
+ return (__m256i)__builtin_ia32_psrldqi256 (__A, __N * 8);
+}
+
+extern __inline __m256i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm256_srli_si256 (__m256i __A, const int __N)
{
return (__m256i)__builtin_ia32_psrldqi256 (__A, __N * 8);
}
#else
+#define _mm256_bsrli_epi128(A, N) \
+ ((__m256i)__builtin_ia32_psrldqi256 ((__m256i)(A), (int)(N) * 8))
#define _mm256_srli_si256(A, N) \
((__m256i)__builtin_ia32_psrldqi256 ((__m256i)(A), (int)(N) * 8))
#endif
diff --git a/gcc/config/i386/emmintrin.h b/gcc/config/i386/emmintrin.h
index ad37fac..b19f05a 100644
--- a/gcc/config/i386/emmintrin.h
+++ b/gcc/config/i386/emmintrin.h
@@ -1165,6 +1165,18 @@ _mm_srai_epi32 (__m128i __A, int __B)
#ifdef __OPTIMIZE__
extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_bsrli_si128 (__m128i __A, const int __N)
+{
+ return (__m128i)__builtin_ia32_psrldqi128 (__A, __N * 8);
+}
+
+extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_bslli_si128 (__m128i __A, const int __N)
+{
+ return (__m128i)__builtin_ia32_pslldqi128 (__A, __N * 8);
+}
+
+extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_srli_si128 (__m128i __A, const int __N)
{
return (__m128i)__builtin_ia32_psrldqi128 (__A, __N * 8);
@@ -1176,6 +1188,10 @@ _mm_slli_si128 (__m128i __A, const int __N)
return (__m128i)__builtin_ia32_pslldqi128 (__A, __N * 8);
}
#else
+#define _mm_bsrli_si128(A, N) \
+ ((__m128i)__builtin_ia32_psrldqi128 ((__m128i)(A), (int)(N) * 8))
+#define _mm_bslli_si128(A, N) \
+ ((__m128i)__builtin_ia32_pslldqi128 ((__m128i)(A), (int)(N) * 8))
#define _mm_srli_si128(A, N) \
((__m128i)__builtin_ia32_psrldqi128 ((__m128i)(A), (int)(N) * 8))
#define _mm_slli_si128(A, N) \
diff --git a/gcc/config/nds32/constants.md b/gcc/config/nds32/constants.md
index 1c37c5f..ea1cd4c 100644
--- a/gcc/config/nds32/constants.md
+++ b/gcc/config/nds32/constants.md
@@ -41,6 +41,7 @@
UNSPEC_VOLATILE_MTUSR
UNSPEC_VOLATILE_SETGIE_EN
UNSPEC_VOLATILE_SETGIE_DIS
+ UNSPEC_VOLATILE_POP25_RETURN
])
;; ------------------------------------------------------------------------
diff --git a/gcc/config/nds32/nds32-protos.h b/gcc/config/nds32/nds32-protos.h
index 328e061..620d897 100644
--- a/gcc/config/nds32/nds32-protos.h
+++ b/gcc/config/nds32/nds32-protos.h
@@ -58,9 +58,9 @@ extern void nds32_init_cumulative_args (CUMULATIVE_ARGS *,
/* -- Function Entry and Exit. */
extern void nds32_expand_prologue (void);
-extern void nds32_expand_epilogue (void);
+extern void nds32_expand_epilogue (bool);
extern void nds32_expand_prologue_v3push (void);
-extern void nds32_expand_epilogue_v3pop (void);
+extern void nds32_expand_epilogue_v3pop (bool);
/* ------------------------------------------------------------------------ */
@@ -120,6 +120,10 @@ extern const char *nds32_output_32bit_load_s (rtx *, int);
extern const char *nds32_output_stack_push (rtx);
extern const char *nds32_output_stack_pop (rtx);
+/* Auxiliary functions to check using return with null epilogue. */
+
+extern int nds32_can_use_return_insn (void);
+
/* Auxiliary functions to decide output alignment or not. */
extern int nds32_target_alignment (rtx);
diff --git a/gcc/config/nds32/nds32.c b/gcc/config/nds32/nds32.c
index f7d5e70..1845bc2 100644
--- a/gcc/config/nds32/nds32.c
+++ b/gcc/config/nds32/nds32.c
@@ -3044,7 +3044,7 @@ nds32_expand_prologue (void)
/* Function for normal multiple pop epilogue. */
void
-nds32_expand_epilogue (void)
+nds32_expand_epilogue (bool sibcall_p)
{
int sp_adjust;
int en4_const;
@@ -3087,12 +3087,10 @@ nds32_expand_epilogue (void)
RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
}
- /* Generate return instruction by using
- unspec_volatile_func_return pattern.
- Make sure this instruction is after gen_blockage().
- NOTE that $lp will become 'live'
- after this instruction has been emitted. */
- emit_insn (gen_unspec_volatile_func_return ());
+ /* Generate return instruction by using 'return_internal' pattern.
+ Make sure this instruction is after gen_blockage(). */
+ if (!sibcall_p)
+ emit_jump_insn (gen_return_internal ());
return;
}
@@ -3196,9 +3194,9 @@ nds32_expand_epilogue (void)
RTX_FRAME_RELATED_P (sp_adjust_insn) = 1;
}
- /* Generate return instruction by using
- unspec_volatile_func_return pattern. */
- emit_insn (gen_unspec_volatile_func_return ());
+ /* Generate return instruction. */
+ if (!sibcall_p)
+ emit_jump_insn (gen_return_internal ());
}
/* Function for v3push prologue. */
@@ -3331,7 +3329,7 @@ nds32_expand_prologue_v3push (void)
/* Function for v3pop epilogue. */
void
-nds32_expand_epilogue_v3pop (void)
+nds32_expand_epilogue_v3pop (bool sibcall_p)
{
int sp_adjust;
@@ -3350,12 +3348,10 @@ nds32_expand_epilogue_v3pop (void)
epilogue code fragment BUT 'ret' instruction. */
if (cfun->machine->naked_p)
{
- /* Generate return instruction by using
- unspec_volatile_func_return pattern.
- Make sure this instruction is after gen_blockage().
- NOTE that $lp will become 'live'
- after this instruction has been emitted. */
- emit_insn (gen_unspec_volatile_func_return ());
+ /* Generate return instruction by using 'return_internal' pattern.
+ Make sure this instruction is after gen_blockage(). */
+ if (!sibcall_p)
+ emit_jump_insn (gen_return_internal ());
return;
}
@@ -3449,6 +3445,28 @@ nds32_expand_epilogue_v3pop (void)
nds32_emit_stack_v3pop (Rb, Re,
GEN_INT (14), GEN_INT (0));
}
+
+ /* Generate return instruction. */
+ emit_jump_insn (gen_pop25return ());
+}
+
+/* Return nonzero if this function is known to have a null epilogue.
+ This allows the optimizer to omit jumps to jumps if no stack
+ was created. */
+int
+nds32_can_use_return_insn (void)
+{
+ /* Prior to reloading, we can't tell how many registers must be saved.
+ Thus we can not determine whether this function has null epilogue. */
+ if (!reload_completed)
+ return 0;
+
+ /* If no stack was created, two conditions must be satisfied:
+ 1. This is a naked function.
+ So there is no callee-saved, local size, or outgoing size.
+ 2. This is NOT a variadic function.
+ So there is no pushing arguement registers into the stack. */
+ return (cfun->machine->naked_p && (cfun->machine->va_args_size == 0));
}
/* ------------------------------------------------------------------------ */
diff --git a/gcc/config/nds32/nds32.md b/gcc/config/nds32/nds32.md
index 8302969..64823a1 100644
--- a/gcc/config/nds32/nds32.md
+++ b/gcc/config/nds32/nds32.md
@@ -1988,6 +1988,102 @@ create_template:
(const_int 4)))])
+;; ----------------------------------------------------------------------------
+
+;; The sibcall patterns.
+
+;; sibcall
+;; sibcall_register
+;; sibcall_immediate
+
+(define_expand "sibcall"
+ [(parallel [(call (match_operand 0 "memory_operand" "")
+ (const_int 0))
+ (clobber (reg:SI TA_REGNUM))
+ (return)])]
+ ""
+ ""
+)
+
+(define_insn "*sibcall_register"
+ [(parallel [(call (mem (match_operand:SI 0 "register_operand" "r, r"))
+ (match_operand 1))
+ (clobber (reg:SI TA_REGNUM))
+ (return)])]
+ ""
+ "@
+ jr5\t%0
+ jr\t%0"
+ [(set_attr "type" "branch,branch")
+ (set_attr "length" " 2, 4")])
+
+(define_insn "*sibcall_immediate"
+ [(parallel [(call (mem (match_operand:SI 0 "immediate_operand" "i"))
+ (match_operand 1))
+ (clobber (reg:SI TA_REGNUM))
+ (return)])]
+ ""
+{
+ if (TARGET_CMODEL_LARGE)
+ return "b\t%0";
+ else
+ return "j\t%0";
+}
+ [(set_attr "type" "branch")
+ (set (attr "length")
+ (if_then_else (match_test "TARGET_CMODEL_LARGE")
+ (const_int 12)
+ (const_int 4)))])
+
+;; sibcall_value
+;; sibcall_value_register
+;; sibcall_value_immediate
+
+(define_expand "sibcall_value"
+ [(parallel [(set (match_operand 0)
+ (call (match_operand 1 "memory_operand" "")
+ (const_int 0)))
+ (clobber (reg:SI TA_REGNUM))
+ (return)])]
+ ""
+ ""
+)
+
+(define_insn "*sibcall_value_register"
+ [(parallel [(set (match_operand 0)
+ (call (mem (match_operand:SI 1 "register_operand" "r, r"))
+ (match_operand 2)))
+ (clobber (reg:SI TA_REGNUM))
+ (return)])]
+ ""
+ "@
+ jr5\t%1
+ jr\t%1"
+ [(set_attr "type" "branch,branch")
+ (set_attr "length" " 2, 4")])
+
+(define_insn "*sibcall_value_immediate"
+ [(parallel [(set (match_operand 0)
+ (call (mem (match_operand:SI 1 "immediate_operand" "i"))
+ (match_operand 2)))
+ (clobber (reg:SI TA_REGNUM))
+ (return)])]
+ ""
+{
+ if (TARGET_CMODEL_LARGE)
+ return "b\t%1";
+ else
+ return "j\t%1";
+}
+ [(set_attr "type" "branch")
+ (set (attr "length")
+ (if_then_else (match_test "TARGET_CMODEL_LARGE")
+ (const_int 12)
+ (const_int 4)))])
+
+
+;; ----------------------------------------------------------------------------
+
;; prologue and epilogue.
(define_expand "prologue" [(const_int 0)]
@@ -2014,9 +2110,23 @@ create_template:
if (TARGET_V3PUSH
&& !nds32_isr_function_p (current_function_decl)
&& (cfun->machine->va_args_size == 0))
- nds32_expand_epilogue_v3pop ();
+ nds32_expand_epilogue_v3pop (false);
else
- nds32_expand_epilogue ();
+ nds32_expand_epilogue (false);
+ DONE;
+})
+
+(define_expand "sibcall_epilogue" [(const_int 0)]
+ ""
+{
+ /* Pass true to indicate that this is sibcall epilogue and
+ exit from a function without the final branch back to the
+ calling function. */
+ if (TARGET_V3PUSH && !nds32_isr_function_p (current_function_decl))
+ nds32_expand_epilogue_v3pop (true);
+ else
+ nds32_expand_epilogue (true);
+
DONE;
})
@@ -2090,17 +2200,27 @@ create_template:
;; ----------------------------------------------------------------------------
-;; unspec operation patterns
+;; Return operation patterns
;; ----------------------------------------------------------------------------
-;; In nds32 target, the 'ret5' instuction is actually 'jr5 $lp'.
-;; This pattern is designed to distinguish function return
-;; from general indirect_jump pattern so that we can directly
-;; generate 'ret5' for readability.
+;; Use this pattern to expand a return instruction
+;; with simple_return rtx if no epilogue is required.
+(define_expand "return"
+ [(simple_return)]
+ "nds32_can_use_return_insn ()"
+ ""
+)
-(define_insn "unspec_volatile_func_return"
- [(set (pc)
- (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_FUNC_RETURN))]
+;; This pattern is expanded only by the shrink-wrapping optimization
+;; on paths where the function prologue has not been executed.
+(define_expand "simple_return"
+ [(simple_return)]
+ ""
+ ""
+)
+
+(define_insn "return_internal"
+ [(simple_return)]
""
{
if (TARGET_16_BIT)
@@ -2108,7 +2228,7 @@ create_template:
else
return "ret";
}
- [(set_attr "type" "misc")
+ [(set_attr "type" "branch")
(set_attr "enabled" "1")
(set (attr "length")
(if_then_else (match_test "TARGET_16_BIT")
@@ -2253,3 +2373,15 @@ create_template:
(set_attr "length" "4")])
;; ----------------------------------------------------------------------------
+
+;; Pseudo NOPs
+
+(define_insn "pop25return"
+ [(return)
+ (unspec_volatile:SI [(reg:SI LP_REGNUM)] UNSPEC_VOLATILE_POP25_RETURN)]
+ ""
+ "! return for pop 25"
+ [(set_attr "length" "0")]
+)
+
+;; ----------------------------------------------------------------------------
diff --git a/gcc/config/rs6000/default64.h b/gcc/config/rs6000/default64.h
index 7536f96..1e7966e 100644
--- a/gcc/config/rs6000/default64.h
+++ b/gcc/config/rs6000/default64.h
@@ -20,7 +20,7 @@ along with GCC; see the file COPYING3. If not see
#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN)
#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (ISA_2_7_MASKS_SERVER | MASK_POWERPC64 | MASK_64BIT | MASK_LITTLE_ENDIAN)
+#define TARGET_DEFAULT (MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_64BIT | MASK_LITTLE_ENDIAN)
#else
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_64BIT)
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index ca21413..3a46333 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1511,10 +1511,8 @@ static const struct attribute_spec rs6000_attribute_table[] =
#undef TARGET_MEMBER_TYPE_FORCES_BLK
#define TARGET_MEMBER_TYPE_FORCES_BLK rs6000_member_type_forces_blk
-/* On rs6000, function arguments are promoted, as are function return
- values. */
#undef TARGET_PROMOTE_FUNCTION_MODE
-#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
+#define TARGET_PROMOTE_FUNCTION_MODE rs6000_promote_function_mode
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
@@ -1678,6 +1676,13 @@ static const struct attribute_spec rs6000_attribute_table[] =
#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV rs6000_atomic_assign_expand_fenv
+
+#undef TARGET_LIBGCC_CMP_RETURN_MODE
+#define TARGET_LIBGCC_CMP_RETURN_MODE rs6000_abi_word_mode
+#undef TARGET_LIBGCC_SHIFT_COUNT_MODE
+#define TARGET_LIBGCC_SHIFT_COUNT_MODE rs6000_abi_word_mode
+#undef TARGET_UNWIND_WORD_MODE
+#define TARGET_UNWIND_WORD_MODE rs6000_abi_word_mode
/* Processor table. */
@@ -9308,6 +9313,29 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
}
}
+/* The mode the ABI uses for a word. This is not the same as word_mode
+ for -m32 -mpowerpc64. This is used to implement various target hooks. */
+
+static machine_mode
+rs6000_abi_word_mode (void)
+{
+ return TARGET_32BIT ? SImode : DImode;
+}
+
+/* On rs6000, function arguments are promoted, as are function return
+ values. */
+
+static machine_mode
+rs6000_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
+ machine_mode mode,
+ int *punsignedp ATTRIBUTE_UNUSED,
+ const_tree, int)
+{
+ PROMOTE_MODE (mode, *punsignedp, type);
+
+ return mode;
+}
+
/* Return true if TYPE must be passed on the stack and not in registers. */
static bool
@@ -11227,7 +11255,7 @@ rs6000_va_start (tree valist, rtx nextarg)
/* Find the overflow area. */
t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
if (words != 0)
- t = fold_build_pointer_plus_hwi (t, words * UNITS_PER_WORD);
+ t = fold_build_pointer_plus_hwi (t, words * MIN_UNITS_PER_WORD);
t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
TREE_SIDE_EFFECTS (t) = 1;
expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index c55d7ed..ef6bb2f 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -733,7 +733,7 @@ extern unsigned char rs6000_recip_bits[];
#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \
if (GET_MODE_CLASS (MODE) == MODE_INT \
- && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
+ && GET_MODE_SIZE (MODE) < (TARGET_32BIT ? 4 : 8)) \
(MODE) = TARGET_32BIT ? SImode : DImode;
/* Define this if most significant bit is lowest numbered
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 889f3c1..ff5fb7a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,14 @@
+2015-01-16 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58614
+ * pt.c (unify): When BRACE_ENCLOSED_INITIALIZER_P (arg), handle
+ TREE_TYPE (elt) == error_mark_node.
+
+2015-01-15 Jan Hubicka <hubicka@ucw.cz>
+
+ PR tree-optimization/62053
+ * tree.c (build_cplus_array_type): Layout type after variants are set.
+
2015-01-15 Jakub Jelinek <jakub@redhat.com>
* cp-gimplify.c (cp_genericize_r): Call
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 55871e5..bc26530 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -17875,6 +17875,8 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
if (!BRACE_ENCLOSED_INITIALIZER_P (elt))
{
tree type = TREE_TYPE (elt);
+ if (type == error_mark_node)
+ return unify_invalid (explain_p);
/* It should only be possible to get here for a call. */
gcc_assert (elt_strict & UNIFY_ALLOW_OUTER_LEVEL);
elt_strict |= maybe_adjust_types_for_deduction
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 80f2ce6..afb57a3 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -881,12 +881,12 @@ build_cplus_array_type (tree elt_type, tree index_type)
{
t = build_min_array_type (elt_type, index_type);
set_array_type_canon (t, elt_type, index_type);
- if (!dependent)
- layout_type (t);
TYPE_MAIN_VARIANT (t) = m;
TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
TYPE_NEXT_VARIANT (m) = t;
+ if (!dependent)
+ layout_type (t);
}
}
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 12368e8e..8a9387b 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -861,12 +861,11 @@ Objective-C and Objective-C++ Dialects}.
-mperf-ext -mno-perf-ext @gol
-mv3push -mno-v3push @gol
-m16bit -mno-16bit @gol
--mgp-direct -mno-gp-direct @gol
-misr-vector-size=@var{num} @gol
-mcache-block-size=@var{num} @gol
-march=@var{arch} @gol
--mforce-fp-as-gp -mforbid-fp-as-gp @gol
--mex9 -mctor-dtor -mrelax}
+-mcmodel=@var{code-model} @gol
+-mctor-dtor -mrelax}
@emph{Nios II Options}
@gccoptlist{-G @var{num} -mgpopt=@var{option} -mgpopt -mno-gpopt @gol
@@ -19153,14 +19152,6 @@ Generate 16-bit instructions.
@opindex mno-16-bit
Do not generate 16-bit instructions.
-@item -mgp-direct
-@opindex mgp-direct
-Generate GP base instructions directly.
-
-@item -mno-gp-direct
-@opindex mno-gp-direct
-Do no generate GP base instructions directly.
-
@item -misr-vector-size=@var{num}
@opindex misr-vector-size
Specify the size of each interrupt vector, which must be 4 or 16.
@@ -19174,20 +19165,20 @@ which must be a power of 2 between 4 and 512.
@opindex march
Specify the name of the target architecture.
-@item -mforce-fp-as-gp
-@opindex mforce-fp-as-gp
-Prevent $fp being allocated during register allocation so that compiler
-is able to force performing fp-as-gp optimization.
-
-@item -mforbid-fp-as-gp
-@opindex mforbid-fp-as-gp
-Forbid using $fp to access static and global variables.
-This option strictly forbids fp-as-gp optimization
-regardless of @option{-mforce-fp-as-gp}.
-
-@item -mex9
-@opindex mex9
-Use special directives to guide linker doing ex9 optimization.
+@item -mcmodel=@var{code-model}
+@opindex mcmodel
+Set the code model to one of
+@table @asis
+@item @samp{small}
+All the data and read-only data segments must be within 512KB addressing space.
+The text segment must be within 16MB addressing space.
+@item @samp{medium}
+The data segment must be within 512KB while the read-only data segment can be
+within 4GB addressing space. The text segment should be still within 16MB
+addressing space.
+@item @samp{large}
+All the text and data segments can be within 4GB addressing space.
+@end table
@item -mctor-dtor
@opindex mctor-dtor
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 4e6c947..9c81fdb 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -11259,18 +11259,25 @@ This target hook is required only when the target has several different
modes and they have different conditional execution capability, such as ARM.
@end deftypefn
-@deftypefn {Target Hook} rtx TARGET_GEN_CCMP_FIRST (int @var{code}, rtx @var{op0}, rtx @var{op1})
-This function emits a comparison insn for the first of a sequence of
- conditional comparisions. It returns a comparison expression appropriate
- for passing to @code{gen_ccmp_next} or @code{cbranch_optab}. @var{code} is
+@deftypefn {Target Hook} rtx TARGET_GEN_CCMP_FIRST (rtx *@var{prep_seq}, rtx *@var{gen_seq}, int @var{code}, tree @var{op0}, tree @var{op1})
+This function prepares to emit a comparison insn for the first compare in a
+ sequence of conditional comparisions. It returns a appropriate @code{CC}
+ for passing to @code{gen_ccmp_next} or @code{cbranch_optab}. The insns to
+ prepare the compare are saved in @var{prep_seq} and the compare insns are
+ saved in @var{gen_seq}. They will be emitted when all the compares in the
+ the conditional comparision are generated without error. @var{code} is
the @code{rtx_code} of the compare for @var{op0} and @var{op1}.
@end deftypefn
-@deftypefn {Target Hook} rtx TARGET_GEN_CCMP_NEXT (rtx @var{prev}, int @var{cmp_code}, rtx @var{op0}, rtx @var{op1}, int @var{bit_code})
-This function emits a conditional comparison within a sequence of
- conditional comparisons. The @var{prev} expression is the result of a
- prior call to @code{gen_ccmp_first} or @code{gen_ccmp_next}. It may return
- @code{NULL} if the combination of @var{prev} and this comparison is
+@deftypefn {Target Hook} rtx TARGET_GEN_CCMP_NEXT (rtx *@var{prep_seq}, rtx *@var{gen_seq}, rtx @var{prev}, int @var{cmp_code}, tree @var{op0}, tree @var{op1}, int @var{bit_code})
+This function prepare to emit a conditional comparison within a sequence of
+ conditional comparisons. It returns a appropriate @code{CC} for passing to
+ @code{gen_ccmp_next} or @code{cbranch_optab}. The insns to prepare the
+ compare are saved in @var{prep_seq} and the compare insns are saved in
+ @var{gen_seq}. They will be emitted when all the compares in the conditional
+ comparision are generated without error. The @var{prev} expression is the
+ result of a prior call to @code{gen_ccmp_first} or @code{gen_ccmp_next}. It
+ may return @code{NULL} if the combination of @var{prev} and this comparison is
not supported, otherwise the result must be appropriate for passing to
@code{gen_ccmp_next} or @code{cbranch_optab}. @var{code} is the
@code{rtx_code} of the compare for @var{op0} and @var{op1}. @var{bit_code}
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 480601c..18e62a0 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -557,6 +557,21 @@ store_bit_field_using_insv (const extraction_insn *insv, rtx op0,
copy_back = true;
}
+ /* There are similar overflow check at the start of store_bit_field_1,
+ but that only check the situation where the field lies completely
+ outside the register, while there do have situation where the field
+ lies partialy in the register, we need to adjust bitsize for this
+ partial overflow situation. Without this fix, pr48335-2.c on big-endian
+ will broken on those arch support bit insert instruction, like arm, aarch64
+ etc. */
+ if (bitsize + bitnum > unit && bitnum < unit)
+ {
+ warning (OPT_Wextra, "write of %wu-bit data outside the bound of "
+ "destination object, data truncated into %wu-bit",
+ bitsize, unit - bitnum);
+ bitsize = unit - bitnum;
+ }
+
/* If BITS_BIG_ENDIAN is zero on a BYTES_BIG_ENDIAN machine, we count
"backwards" from the size of the unit we are inserting into.
Otherwise, we count bits from the most significant on a
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 3fd3cfb..c97de7f 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,9 @@
+2015-01-16 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/45290
+ * decl.c (match_pointer_init): Error out if resolution of init expr
+ failed.
+
2015-01-15 Tobias Burnus <burnus@net-b.de>
* openmp.c (check_symbol_not_pointer, resolve_oacc_data_clauses,
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index dfb760b..2a200fc 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -1780,8 +1780,8 @@ match_pointer_init (gfc_expr **init, int procptr)
return MATCH_ERROR;
}
- if (!procptr)
- gfc_resolve_expr (*init);
+ if (!procptr && !gfc_resolve_expr (*init))
+ return MATCH_ERROR;
if (!gfc_notify_std (GFC_STD_F2008, "non-NULL pointer "
"initialization at %C"))
diff --git a/gcc/ipa-chkp.c b/gcc/ipa-chkp.c
index 30d511d..8e6612e 100644
--- a/gcc/ipa-chkp.c
+++ b/gcc/ipa-chkp.c
@@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. If not see
#include "lto-streamer.h"
#include "cgraph.h"
#include "tree-chkp.h"
+#include "tree-inline.h"
#include "ipa-chkp.h"
/* Pointer Bounds Checker has two IPA passes to support code instrumentation.
@@ -401,6 +402,18 @@ chkp_maybe_clone_builtin_fndecl (tree fndecl)
return clone;
}
+/* Return 1 if function FNDECL should be instrumented. */
+
+bool
+chkp_instrumentable_p (tree fndecl)
+{
+ struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
+ return (!lookup_attribute ("bnd_legacy", DECL_ATTRIBUTES (fndecl))
+ && (!flag_chkp_instrument_marked_only
+ || lookup_attribute ("bnd_instrument", DECL_ATTRIBUTES (fndecl)))
+ && (!fn || !copy_forbidden (fn, fndecl)));
+}
+
/* Return clone created for instrumentation of NODE or NULL. */
cgraph_node *
@@ -483,10 +496,10 @@ chkp_maybe_create_clone (tree fndecl)
{
/* If function will not be instrumented, then it's instrumented
version is a thunk for the original. */
- if (lookup_attribute ("bnd_legacy", DECL_ATTRIBUTES (fndecl))
- || (flag_chkp_instrument_marked_only
- && !lookup_attribute ("bnd_instrument", DECL_ATTRIBUTES (fndecl))))
+ if (!chkp_instrumentable_p (fndecl))
{
+ clone->remove_callees ();
+ clone->remove_all_references ();
clone->thunk.thunk_p = true;
clone->thunk.add_pointer_bounds_args = true;
clone->create_edge (node, NULL, 0, CGRAPH_FREQ_BASE);
@@ -532,7 +545,8 @@ chkp_maybe_create_clone (tree fndecl)
/* Clone all thunks. */
for (e = node->callers; e; e = e->next_caller)
- if (e->caller->thunk.thunk_p)
+ if (e->caller->thunk.thunk_p
+ && !e->caller->thunk.add_pointer_bounds_args)
{
struct cgraph_node *thunk
= chkp_maybe_create_clone (e->caller->decl);
@@ -578,6 +592,7 @@ static unsigned int
chkp_versioning (void)
{
struct cgraph_node *node;
+ const char *reason;
bitmap_obstack_initialize (NULL);
@@ -587,14 +602,20 @@ chkp_versioning (void)
&& !node->instrumented_version
&& !node->alias
&& !node->thunk.thunk_p
- && !lookup_attribute ("bnd_legacy", DECL_ATTRIBUTES (node->decl))
- && (!flag_chkp_instrument_marked_only
- || lookup_attribute ("bnd_instrument",
- DECL_ATTRIBUTES (node->decl)))
&& (!DECL_BUILT_IN (node->decl)
|| (DECL_BUILT_IN_CLASS (node->decl) == BUILT_IN_NORMAL
&& DECL_FUNCTION_CODE (node->decl) < BEGIN_CHKP_BUILTINS)))
- chkp_maybe_create_clone (node->decl);
+ {
+ if (chkp_instrumentable_p (node->decl))
+ chkp_maybe_create_clone (node->decl);
+ else if ((reason = copy_forbidden (DECL_STRUCT_FUNCTION (node->decl),
+ node->decl)))
+ {
+ if (warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wchkp,
+ "function cannot be instrumented"))
+ inform (DECL_SOURCE_LOCATION (node->decl), reason, node->decl);
+ }
+ }
}
/* Mark all aliases and thunks of functions with no instrumented
diff --git a/gcc/ipa-chkp.h b/gcc/ipa-chkp.h
index b087227..6708fe9 100644
--- a/gcc/ipa-chkp.h
+++ b/gcc/ipa-chkp.h
@@ -23,5 +23,6 @@ along with GCC; see the file COPYING3. If not see
extern tree chkp_copy_function_type_adding_bounds (tree orig_type);
extern tree chkp_maybe_clone_builtin_fndecl (tree fndecl);
extern cgraph_node *chkp_maybe_create_clone (tree fndecl);
+extern bool chkp_instrumentable_p (tree fndecl);
#endif /* GCC_IPA_CHKP_H */
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 1a227a2..f270cfa 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -1655,7 +1655,18 @@ inline_small_functions (void)
reset_edge_growth_cache (edge);
gcc_assert (old_size_est == estimate_edge_size (edge));
gcc_assert (old_time_est == estimate_edge_time (edge));
- gcc_assert (old_hints_est == estimate_edge_hints (edge));
+ /* FIXME:
+
+ gcc_assert (old_hints_est == estimate_edge_hints (edge));
+
+ fails with profile feedback because some hints depends on
+ maybe_hot_edge_p predicate and because callee gets inlined to other
+ calls, the edge may become cold.
+ This ought to be fixed by computing relative probabilities
+ for given invocation but that will be better done once whole
+ code is converted to sreals. Disable for now and revert to "wrong"
+ value so enable/disable checking paths agree. */
+ edge_growth_cache[edge->uid].hints = old_hints_est + 1;
/* When updating the edge costs, we only decrease badness in the keys.
Increases of badness are handled lazilly; when we see key with out
diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog
index ad5382a..1bd439a 100644
--- a/gcc/jit/ChangeLog
+++ b/gcc/jit/ChangeLog
@@ -1,3 +1,12 @@
+2015-01-16 Jakub Jelinek <jakub@redhat.com>
+
+ * jit-builtins.h (DEF_FUNCTION_TYPE_VAR_5): Fix spelling of
+ last argument.
+ (DEF_FUNCTION_TYPE_VAR_8, DEF_FUNCTION_TYPE_VAR_12): Define and
+ undef afterwards.
+ * jit-builtins.c (DEF_FUNCTION_TYPE_VAR_8, DEF_FUNCTION_TYPE_VAR_12):
+ Likewise.
+
2015-01-15 Richard Sandiford <richard.sandiford@arm.com>
Update copyright years in docs/.
diff --git a/gcc/jit/jit-builtins.c b/gcc/jit/jit-builtins.c
index 871f63e..47b0198 100644
--- a/gcc/jit/jit-builtins.c
+++ b/gcc/jit/jit-builtins.c
@@ -313,6 +313,15 @@ builtins_manager::make_type (enum jit_builtin_type type_id)
case ENUM: return make_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
#define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
case ENUM: return make_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
+#define DEF_FUNCTION_TYPE_VAR_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
+ ARG6, ARG7, ARG8) \
+ case ENUM: return make_fn_type (ENUM, RETURN, 1, 8, ARG1, ARG2, ARG3, \
+ ARG4, ARG5, ARG6, ARG7, ARG8);
+#define DEF_FUNCTION_TYPE_VAR_12(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
+ ARG6, ARG7, ARG8, ARG9, ARG10, ARG11, ARG12) \
+ case ENUM: return make_fn_type (ENUM, RETURN, 1, 12, ARG1, ARG2, ARG3, \
+ ARG4, ARG5, ARG6, ARG7, ARG8, ARG9, \
+ ARG10, ARG11, ARG12);
#define DEF_POINTER_TYPE(ENUM, TYPE) \
case ENUM: return make_ptr_type (ENUM, TYPE);
@@ -334,6 +343,8 @@ builtins_manager::make_type (enum jit_builtin_type type_id)
#undef DEF_FUNCTION_TYPE_VAR_3
#undef DEF_FUNCTION_TYPE_VAR_4
#undef DEF_FUNCTION_TYPE_VAR_5
+#undef DEF_FUNCTION_TYPE_VAR_8
+#undef DEF_FUNCTION_TYPE_VAR_12
#undef DEF_POINTER_TYPE
default:
diff --git a/gcc/jit/jit-builtins.h b/gcc/jit/jit-builtins.h
index e6a0cd4..9101aaf 100644
--- a/gcc/jit/jit-builtins.h
+++ b/gcc/jit/jit-builtins.h
@@ -45,7 +45,12 @@ enum jit_builtin_type
#define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
#define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
#define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
-#define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG6) \
+#define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
+ NAME,
+#define DEF_FUNCTION_TYPE_VAR_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
+ ARG6, ARG7, ARG8) NAME,
+#define DEF_FUNCTION_TYPE_VAR_12(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
+ ARG6, ARG7, ARG8, ARG9, ARG10, ARG11, ARG12) \
NAME,
#define DEF_POINTER_TYPE(NAME, TYPE) NAME,
#include "builtin-types.def"
@@ -65,6 +70,8 @@ enum jit_builtin_type
#undef DEF_FUNCTION_TYPE_VAR_3
#undef DEF_FUNCTION_TYPE_VAR_4
#undef DEF_FUNCTION_TYPE_VAR_5
+#undef DEF_FUNCTION_TYPE_VAR_8
+#undef DEF_FUNCTION_TYPE_VAR_12
#undef DEF_POINTER_TYPE
BT_LAST
}; /* enum jit_builtin_type */
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index f102fe5..6e4be72 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -3802,6 +3802,8 @@ curr_insn_transform (bool check_only_p)
(ira_class_hard_regs[goal_alt[i]][0],
GET_MODE (reg), byte, mode) >= 0)))))
{
+ if (type == OP_OUT)
+ type = OP_INOUT;
loc = &SUBREG_REG (*loc);
mode = GET_MODE (*loc);
}
diff --git a/gcc/optc-save-gen.awk b/gcc/optc-save-gen.awk
index add0949..58732c0 100644
--- a/gcc/optc-save-gen.awk
+++ b/gcc/optc-save-gen.awk
@@ -505,9 +505,9 @@ print "";
print "/* Print different target option variables from structures provided as arguments. */";
print "void";
print "cl_target_option_print_diff (FILE *file,";
-print " int indent,";
-print " struct cl_target_option *ptr1,";
-print " struct cl_target_option *ptr2)";
+print " int indent ATTRIBUTE_UNUSED,";
+print " struct cl_target_option *ptr1 ATTRIBUTE_UNUSED,";
+print " struct cl_target_option *ptr2 ATTRIBUTE_UNUSED)";
print "{";
print " fputs (\"\\n\", file);";
diff --git a/gcc/params.def b/gcc/params.def
index cbdc477..3f69ce0 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -198,7 +198,7 @@ DEFPARAM(PARAM_IPCP_UNIT_GROWTH,
DEFPARAM(PARAM_EARLY_INLINING_INSNS,
"early-inlining-insns",
"Maximal estimated growth of function body caused by early inlining of single call",
- 11, 0, 0)
+ 14, 0, 0)
DEFPARAM(PARAM_LARGE_STACK_FRAME,
"large-stack-frame",
"The size of stack frame to be considered large",
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 4ee63d2..d26267d 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -539,9 +539,15 @@ simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
- /* (lo_sum (high x) x) -> x */
- if (GET_CODE (op0) == HIGH && rtx_equal_p (XEXP (op0, 0), op1))
- return op1;
+ /* (lo_sum (high x) y) -> y where x and y have the same base. */
+ if (GET_CODE (op0) == HIGH)
+ {
+ rtx base0, base1, offset0, offset1;
+ split_const (XEXP (op0, 0), &base0, &offset0);
+ split_const (op1, &base1, &offset1);
+ if (rtx_equal_p (base0, base1))
+ return op1;
+ }
if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
return x;
diff --git a/gcc/target.def b/gcc/target.def
index 4aebcfe..356f7c1 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2542,24 +2542,31 @@ modes and they have different conditional execution capability, such as ARM.",
DEFHOOK
(gen_ccmp_first,
- "This function emits a comparison insn for the first of a sequence of\n\
- conditional comparisions. It returns a comparison expression appropriate\n\
- for passing to @code{gen_ccmp_next} or @code{cbranch_optab}. @var{code} is\n\
+ "This function prepares to emit a comparison insn for the first compare in a\n\
+ sequence of conditional comparisions. It returns a appropriate @code{CC}\n\
+ for passing to @code{gen_ccmp_next} or @code{cbranch_optab}. The insns to\n\
+ prepare the compare are saved in @var{prep_seq} and the compare insns are\n\
+ saved in @var{gen_seq}. They will be emitted when all the compares in the\n\
+ the conditional comparision are generated without error. @var{code} is\n\
the @code{rtx_code} of the compare for @var{op0} and @var{op1}.",
- rtx, (int code, rtx op0, rtx op1),
+ rtx, (rtx *prep_seq, rtx *gen_seq, int code, tree op0, tree op1),
NULL)
DEFHOOK
(gen_ccmp_next,
- "This function emits a conditional comparison within a sequence of\n\
- conditional comparisons. The @var{prev} expression is the result of a\n\
- prior call to @code{gen_ccmp_first} or @code{gen_ccmp_next}. It may return\n\
- @code{NULL} if the combination of @var{prev} and this comparison is\n\
+ "This function prepare to emit a conditional comparison within a sequence of\n\
+ conditional comparisons. It returns a appropriate @code{CC} for passing to\n\
+ @code{gen_ccmp_next} or @code{cbranch_optab}. The insns to prepare the\n\
+ compare are saved in @var{prep_seq} and the compare insns are saved in\n\
+ @var{gen_seq}. They will be emitted when all the compares in the conditional\n\
+ comparision are generated without error. The @var{prev} expression is the\n\
+ result of a prior call to @code{gen_ccmp_first} or @code{gen_ccmp_next}. It\n\
+ may return @code{NULL} if the combination of @var{prev} and this comparison is\n\
not supported, otherwise the result must be appropriate for passing to\n\
@code{gen_ccmp_next} or @code{cbranch_optab}. @var{code} is the\n\
@code{rtx_code} of the compare for @var{op0} and @var{op1}. @var{bit_code}\n\
is @code{AND} or @code{IOR}, which is the op on the two compares.",
- rtx, (rtx prev, int cmp_code, rtx op0, rtx op1, int bit_code),
+ rtx, (rtx *prep_seq, rtx *gen_seq, rtx prev, int cmp_code, tree op0, tree op1, int bit_code),
NULL)
/* Return a new value for loop unroll size. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1ea322b..57e4936 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,77 @@
+2015-01-16 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR middle-end/64353
+ * g++.dg/pr64353.C: New.
+
+2015-01-16 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR target/64263
+ * gcc.target/aarch64/pr64263_1.c: New test.
+
+2015-01-16 Yuri Rumyantsev <ysrumyan@gmail.com>
+
+ PR tree-optimization/64434
+ * gcc.dg/torture/pr64434.c: Move to...
+ * gcc.dg/pr64434.c: ... here.
+
+2015-01-16 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/64614
+ * gcc.dg/uninit-18.c: New testcase.
+
+2015-01-16 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/64568
+ * g++.dg/torture/pr64568-2.C: New testcase.
+
+2015-01-16 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR target/64363
+ * gcc.target/i386/chkp-label-address.c: New.
+
+2015-01-16 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/45290
+ * gfortran.dg/pointer_init_6.f90: Extended.
+
+2015-01-16 Robert Suchanek <robert.suchanek@imgtec.com>
+
+ * gcc.c-torture/compile/20150108.c: New test.
+
+2015-01-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.target/visium: New directory.
+
+2015-01-16 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/61743
+ * gcc.dg/tree-ssa/pr61743-1.c: Add -fno-tree-vectorize.
+ * gcc.dg/tree-ssa/pr61743-2.c: Likewise.
+
+2015-01-16 Zhenqiang Chen <zhenqiang.chen@arm.com>
+
+ * gcc.dg/pr64015.c: New test.
+
+2015-01-16 Markus Trippelsdorf <markus@trippelsdorf.de>
+
+ PR ipa/64163
+ PR ipa/64612
+ * g++.dg/ipa/pr64612.C: New test.
+
+2015-01-16 Renlin Li <renlin.li@arm.com>
+
+ * g++.dg/builtin-apply2.c: Remove aarch64 target from skip list.
+
+2015-01-16 Ilya Tocar <ilya.tocar@intel.com>
+
+ * gcc.target/i386/sse-14.c: Test new intrinsic.
+ * gcc.target/i386/sse-22.c: Ditto.
+
+2015-01-16 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58614
+ * g++.dg/cpp0x/auto44.C: New.
+
2015-01-15 Sandra Loosemore <sandra@codesourcery.com>
PR target/59710
@@ -489,7 +563,7 @@
PR tree-optimization/64404
* gcc.dg/vect/pr64404.c: New testcase.
-2014-01-13 Richard Biener <rguenther@suse.de>
+2015-01-13 Richard Biener <rguenther@suse.de>
PR tree-optimization/64568
* g++.dg/torture/pr64568.C: New testcase.
diff --git a/gcc/testsuite/g++.dg/cpp0x/auto44.C b/gcc/testsuite/g++.dg/cpp0x/auto44.C
new file mode 100644
index 0000000..687f154
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/auto44.C
@@ -0,0 +1,10 @@
+// PR c++/58614
+// { dg-do compile { target c++11 } }
+
+#include <initializer_list>
+
+void foo()
+{
+ i; // { dg-error "not declared" }
+ auto j = { i }; // { dg-error "unable to deduce" }
+}
diff --git a/gcc/testsuite/g++.dg/ipa/pr64612.C b/gcc/testsuite/g++.dg/ipa/pr64612.C
new file mode 100644
index 0000000..f1cd96a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr64612.C
@@ -0,0 +1,66 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -std=c++11" } */
+/* { dg-final { scan-assembler "_ZN5QListI7QStringED1Ev" } } */
+
+class A
+{
+public:
+ bool deref ();
+};
+class QString;
+struct B
+{
+ A ref;
+};
+template <typename> class QList
+{
+ B d;
+public:
+ ~QList ();
+ class const_iterator
+ {
+ };
+ const_iterator constBegin ();
+ void clear ();
+ void dealloc ();
+};
+template <typename T> QList<T>::~QList ()
+{
+ if (d.ref.deref ())
+ dealloc ();
+}
+template <typename T>
+void
+QList<T>::clear ()
+{
+ QList ();
+}
+class A1 : public QList<QString>
+{
+};
+class B1
+{
+public:
+ B1 (A1);
+};
+struct F
+{
+ void addMatch (const QString &&);
+ A1 m_matchingMimeTypes;
+};
+class G
+{
+ A1 matchingGlobs (const QString &) const;
+};
+void
+F::addMatch (const QString &&)
+{
+ m_matchingMimeTypes.clear ();
+}
+A1
+G::matchingGlobs (const QString &) const
+{
+ A1 a;
+ for (B1 b (a);;)
+ ;
+}
diff --git a/gcc/testsuite/g++.dg/pr64353.C b/gcc/testsuite/g++.dg/pr64353.C
new file mode 100644
index 0000000..7859918
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr64353.C
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+class C
+{
+ int y, x;
+ void i ();
+ bool __attribute__((const)) xx () { return x; }
+};
+
+void C::i ()
+{
+ if (xx ())
+ x = 1;
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr64568-2.C b/gcc/testsuite/g++.dg/torture/pr64568-2.C
new file mode 100644
index 0000000..0578217
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr64568-2.C
@@ -0,0 +1,146 @@
+// { dg-do compile }
+
+namespace std
+{
+ typedef __SIZE_TYPE__ size_t;
+}
+class H;
+namespace std
+{
+ template <typename> struct complex;
+ template <typename _Tp>
+ complex<_Tp> operator+(complex<_Tp> &__x, complex<_Tp> __y)
+ {
+ complex<_Tp> a = __x;
+ a += __y;
+ return a;
+ }
+ template <> struct complex<double>
+ {
+ int
+ imag ()
+ {
+ return __imag__ _M_value;
+ }
+ void operator+=(complex __z) { _M_value += _M_value; _M_value += __z.imag (); }
+ _Complex double _M_value;
+ };
+}
+struct A
+{
+ typedef std::complex<double> &const_reference;
+};
+class B
+{
+public:
+ B (int);
+ std::complex<double> &operator[](int i) { return data_[i]; }
+ std::complex<double> *data_;
+};
+struct C
+{
+ static std::complex<double>
+ apply (A::const_reference t1, std::complex<double> t2)
+ {
+ return t1 + t2;
+ }
+ typedef std::complex<double> result_type;
+};
+template <class T1, class> struct D
+{
+ static void
+ apply (T1 t1, std::complex<double> t2)
+ {
+ t1 = t2;
+ }
+};
+class ublas_expression
+{
+public:
+ ~ublas_expression ();
+};
+template <class> class F
+{
+};
+template <class E> class matrix_expression : ublas_expression
+{
+public:
+ E &operator()() {}
+};
+class I : public F<int>
+{
+public:
+ typedef int value_type;
+ I (int);
+};
+template <class E1, class E2> matrix_expression<int> outer_prod (F<E1>, F<E2>);
+template <class E1, class F> class J : public matrix_expression<J<E1, F> >
+{
+public:
+ typedef typename F::result_type value_type;
+ value_type operator()(int i, int)
+ {
+ return F::apply (e1_ (i, 0), e2_ (0, 0));
+ }
+ E1 e1_;
+ E1 e2_;
+};
+template <class E1, class E2>
+J<H, C> operator+(matrix_expression<E1>, matrix_expression<E2>);
+template <template <class, class> class F, class M, class E>
+void
+indexing_matrix_assign (M m, matrix_expression<E> e, int)
+{
+ for (int i; i; ++i)
+ F<typename M::reference, typename E::value_type>::apply (m (0, 0),
+ e ()(i, 0));
+}
+template <template <class, class> class F, class, class M, class E, class C>
+void
+matrix_assign (M m, matrix_expression<E> e, int, C)
+{
+ indexing_matrix_assign<F> (m, e, 0);
+}
+template <template <class, class> class F, class M, class E>
+void
+matrix_assign (M m, matrix_expression<E> e)
+{
+ matrix_assign<F, int> (m, e, 0, typename M::orientation_category ());
+}
+class H : matrix_expression<int>
+{
+public:
+ typedef std::complex<double> &reference;
+ typedef int orientation_category;
+ H (int, int) : data_ (0) {}
+ template <class AE> H (matrix_expression<AE> ae) : data_ (0)
+ {
+ matrix_assign<D> (*this, ae);
+ }
+ B &
+ data ()
+ {
+ }
+ std::complex<double> &operator()(int i, int) { return data ()[i]; }
+ void operator+=(matrix_expression ae) { H (*this + ae); }
+ B data_;
+};
+template <class M, class T, class V1, class V2>
+void
+sr2 (M m, T, V1 v1, V2 v2)
+{
+ m += outer_prod (v2, v1);
+}
+template <class, class, std::size_t> struct G
+{
+ void test ();
+};
+template struct G<I, H, 3>;
+template <class V, class M, std::size_t N>
+void
+G<V, M, N>::test ()
+{
+ V b (0), c (0);
+ M m (0, 0);
+ sr2 (m, typename V::value_type (), b, c);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/20150108.c b/gcc/testsuite/gcc.c-torture/compile/20150108.c
new file mode 100644
index 0000000..15c53e3
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20150108.c
@@ -0,0 +1,23 @@
+long long a[10];
+long long b, c, d, k, m, n, o, p, q, r, s, t, u, v, w;
+int e, f, g, h, i, j, l, x;
+
+int fn1 () {
+ for (; x; x++)
+ if (x & 1)
+ s = h | g;
+ else
+ s = f | e;
+ l = ~0;
+ m = 1 | k;
+ n = i;
+ o = j;
+ p = f | e;
+ q = h | g;
+ w = d | c | a[1];
+ t = c;
+ v = b | c;
+ u = v;
+ r = b | a[4];
+ return e;
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-apply2.c b/gcc/testsuite/gcc.dg/builtin-apply2.c
index d666fcc..b6cbe39 100644
--- a/gcc/testsuite/gcc.dg/builtin-apply2.c
+++ b/gcc/testsuite/gcc.dg/builtin-apply2.c
@@ -1,6 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target untyped_assembly } */
-/* { dg-skip-if "Variadic funcs have all args on stack. Normal funcs have args in registers." { "aarch64*-*-* avr-*-* nds32*-*-*" } { "*" } { "" } } */
+/* { dg-skip-if "Variadic funcs have all args on stack. Normal funcs have args in registers." { "avr-*-* nds32*-*-*" } { "*" } { "" } } */
/* { dg-skip-if "Variadic funcs use Base AAPCS. Normal funcs use VFP variant." { arm*-*-* && arm_hf_eabi } { "*" } { "" } } */
/* PR target/12503 */
diff --git a/gcc/testsuite/gcc.dg/pr64015.c b/gcc/testsuite/gcc.dg/pr64015.c
new file mode 100644
index 0000000..daf8393
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr64015.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 " } */
+
+int
+test (unsigned short a, unsigned char b)
+{
+ return a > 0xfff2 && b > 252;
+}
+
+/* { dg-final { scan-assembler "ccmp" { target aarch64*-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/torture/pr64434.c b/gcc/testsuite/gcc.dg/pr64434.c
index 60fc806..60fc806 100644
--- a/gcc/testsuite/gcc.dg/torture/pr64434.c
+++ b/gcc/testsuite/gcc.dg/pr64434.c
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr61743-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr61743-1.c
index de09daa..5e45c2d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr61743-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr61743-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -funroll-loops -fdump-tree-cunroll-details" } */
+/* { dg-options "-O3 -funroll-loops -fno-tree-vectorize -fdump-tree-cunroll-details" } */
#define N 8
#define M 14
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr61743-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr61743-2.c
index c8a4391..7bc8e35 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr61743-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr61743-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -funroll-loops -fdump-tree-cunroll-details" } */
+/* { dg-options "-O3 -funroll-loops -fno-tree-vectorize -fdump-tree-cunroll-details" } */
#define N 8
#define M 14
diff --git a/gcc/testsuite/gcc.dg/uninit-18.c b/gcc/testsuite/gcc.dg/uninit-18.c
new file mode 100644
index 0000000..223983e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/uninit-18.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O -Wuninitialized" } */
+
+char *foo(int bar, char *baz)
+{
+ char *tmp;
+
+ if (bar & 3)
+ tmp = baz;
+
+ switch (bar) {
+ case 1:
+ tmp[5] = 7; /* { dg-bogus "may be used uninitialized" } */
+ break;
+ case 2:
+ tmp[11] = 15; /* { dg-bogus "may be used uninitialized" } */
+ break;
+ default:
+ tmp = 0;
+ break;
+ }
+
+ return tmp; /* { dg-bogus "may be used uninitialized" } */
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/pr64263_1.c b/gcc/testsuite/gcc.target/aarch64/pr64263_1.c
new file mode 100644
index 0000000..047e623
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr64263_1.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+#include "arm_neon.h"
+
+extern long int vget_lane_s64_1 (int64x1_t, const int);
+
+void
+foo ()
+{
+ int8x8_t val14;
+ int8x8_t val15;
+ uint8x8_t val16;
+ uint32x4_t val40;
+ val14 = vcreate_s8 (0xff0080f6807f807fUL);
+ val15 = vcreate_s8 (0x10807fff7f808080UL);
+ val16 = vcgt_s8 (val14, val15);
+ val40 = vreinterpretq_u32_u64 (
+ vdupq_n_u64 (
+ vget_lane_s64_1 (
+ vreinterpret_s64_u8 (val16), 0)
+ ));
+}
diff --git a/gcc/testsuite/gcc.target/i386/chkp-label-address.c b/gcc/testsuite/gcc.target/i386/chkp-label-address.c
new file mode 100644
index 0000000..05963e2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/chkp-label-address.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target mpx } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx -O2 -Wchkp" } */
+
+#include <stdio.h>
+
+static int f1 () /* { dg-warning "function cannot be instrumented" "" } */
+{
+ static int array = &&label_B - &&label_A;
+
+ label_A:
+
+ printf ("%d\n", array);
+
+ label_B:
+
+ return 0;
+}
+
+int f2 (int i)
+{
+ printf ("%d\n", i);
+ return f1 ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse-14.c b/gcc/testsuite/gcc.target/i386/sse-14.c
index f3f6c5c..e8791e3 100644
--- a/gcc/testsuite/gcc.target/i386/sse-14.c
+++ b/gcc/testsuite/gcc.target/i386/sse-14.c
@@ -601,6 +601,8 @@ test_2 (_mm_alignr_pi8, __m64, __m64, __m64, 1)
/* emmintrin.h */
test_2 (_mm_shuffle_pd, __m128d, __m128d, __m128d, 1)
+test_1 (_mm_bsrli_si128, __m128i, __m128i, 1)
+test_1 (_mm_bslli_si128, __m128i, __m128i, 1)
test_1 (_mm_srli_si128, __m128i, __m128i, 1)
test_1 (_mm_slli_si128, __m128i, __m128i, 1)
test_1 (_mm_extract_epi16, int, __m128i, 1)
diff --git a/gcc/testsuite/gcc.target/i386/sse-22.c b/gcc/testsuite/gcc.target/i386/sse-22.c
index 0d7bd16..72017f5 100644
--- a/gcc/testsuite/gcc.target/i386/sse-22.c
+++ b/gcc/testsuite/gcc.target/i386/sse-22.c
@@ -138,6 +138,8 @@ test_1 (_mm_prefetch, void, void *, _MM_HINT_NTA)
#endif
#include <emmintrin.h>
test_2 (_mm_shuffle_pd, __m128d, __m128d, __m128d, 1)
+test_1 (_mm_bsrli_si128, __m128i, __m128i, 1)
+test_1 (_mm_bslli_si128, __m128i, __m128i, 1)
test_1 (_mm_srli_si128, __m128i, __m128i, 1)
test_1 (_mm_slli_si128, __m128i, __m128i, 1)
test_1 (_mm_extract_epi16, int, __m128i, 1)
@@ -269,6 +271,8 @@ test_2 ( _mm256_blend_epi16, __m256i, __m256i, __m256i, 1)
test_1 ( _mm256_shuffle_epi32, __m256i, __m256i, 1)
test_1 ( _mm256_shufflehi_epi16, __m256i, __m256i, 1)
test_1 ( _mm256_shufflelo_epi16, __m256i, __m256i, 1)
+test_1 ( _mm256_bslli_epi128, __m256i, __m256i, 8)
+test_1 ( _mm256_bsrli_epi128, __m256i, __m256i, 8)
test_1 ( _mm256_slli_si256, __m256i, __m256i, 8)
test_1 ( _mm256_srli_si256, __m256i, __m256i, 8)
test_2 ( _mm_blend_epi32, __m128i, __m128i, __m128i, 1)
diff --git a/gcc/testsuite/gcc.target/visium/bit_shift.c b/gcc/testsuite/gcc.target/visium/bit_shift.c
new file mode 100644
index 0000000..bf37342
--- /dev/null
+++ b/gcc/testsuite/gcc.target/visium/bit_shift.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+int bit_shift (long int x)
+{
+ int i, n;
+
+ for (i = n = 0; x && (i < (sizeof(long) * 8)); ++i, x >>= 1)
+ n += (int)(x & 1L);
+ return n;
+}
+
+/* { dg-final { scan-assembler-not "cmp" } } */
diff --git a/gcc/testsuite/gcc.target/visium/bit_test.c b/gcc/testsuite/gcc.target/visium/bit_test.c
new file mode 100644
index 0000000..2de9208f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/visium/bit_test.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+extern void bar (void);
+
+void foo1 (unsigned int i)
+{
+ if (i & 4)
+ bar ();
+}
+
+void foo2 (unsigned int i)
+{
+ if (i & 0x80000000)
+ bar ();
+}
+
+void foo3 (unsigned char c)
+{
+ if (c & 4)
+ bar ();
+}
+
+void foo4 (unsigned char c)
+{
+ if (c & 0x80)
+ bar ();
+}
+
+/* { dg-final { scan-assembler-times "lsr.l" 2 } } */
+/* { dg-final { scan-assembler-times "cmp" 2 } } */
diff --git a/gcc/testsuite/gcc.target/visium/block_move.c b/gcc/testsuite/gcc.target/visium/block_move.c
new file mode 100644
index 0000000..a9e3522
--- /dev/null
+++ b/gcc/testsuite/gcc.target/visium/block_move.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O -mcpu=gr6" } */
+
+extern void abort (void);
+
+#define LEN 256
+
+void foo (void)
+{
+ int dst[LEN], src[LEN];
+ unsigned int i;
+
+ __builtin_memset (src, 0, LEN * sizeof (int));
+ __builtin_memcpy (dst, src, LEN * sizeof (int));
+ if (__builtin_memcmp (dst, src, LEN * sizeof (int)) != 0)
+ abort ();
+}
+
+/* { dg-final { scan-assembler "bmd" } } */
diff --git a/gcc/testsuite/gcc.target/visium/cstore_eq.c b/gcc/testsuite/gcc.target/visium/cstore_eq.c
new file mode 100644
index 0000000..2bc132a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/visium/cstore_eq.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+int foo1 (int i)
+{
+ return (i != 0);
+}
+
+int foo2 (int i)
+{
+ return (i == 0);
+}
+
+int foo3 (int a, int b)
+{
+ return a != b;
+}
+
+int foo4 (int a, int b)
+{
+ return (a == b);
+}
+
+/* { dg-final { scan-assembler-times "adc.l" 2 } } */
+/* { dg-final { scan-assembler-times "subc.l" 2 } } */
diff --git a/gcc/testsuite/gcc.target/visium/cstore_fp.c b/gcc/testsuite/gcc.target/visium/cstore_fp.c
new file mode 100644
index 0000000..8849d1f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/visium/cstore_fp.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fno-trapping-math" } */
+
+int foo1 (float a, float b)
+{
+ return (a < b);
+}
+
+int foo2 (float a, float b)
+{
+ return (a > b);
+}
+
+int foo3 (float a, float b)
+{
+ return !(a < b);
+}
+
+int foo4 (float a, float b)
+{
+ return !(a > b);
+}
+
+/* { dg-final { scan-assembler-times "adc.l" 2 } } */
+/* { dg-final { scan-assembler-times "subc.l" 2 } } */
diff --git a/gcc/testsuite/gcc.target/visium/cstore_uns.c b/gcc/testsuite/gcc.target/visium/cstore_uns.c
new file mode 100644
index 0000000..c60f984
--- /dev/null
+++ b/gcc/testsuite/gcc.target/visium/cstore_uns.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+int foo1 (unsigned a, unsigned b)
+{
+ return (a < b);
+}
+
+int foo2 (unsigned a, unsigned b)
+{
+ return (a > b);
+}
+
+int foo3 (unsigned a, unsigned b)
+{
+ return (a >= b);
+}
+
+int foo4 (unsigned a, unsigned b)
+{
+ return (a <= b);
+}
+
+/* { dg-final { scan-assembler-times "adc.l" 2 } } */
+/* { dg-final { scan-assembler-times "subc.l" 2 } } */
diff --git a/gcc/testsuite/gcc.target/visium/long_branch.c b/gcc/testsuite/gcc.target/visium/long_branch.c
new file mode 100644
index 0000000..a53537a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/visium/long_branch.c
@@ -0,0 +1,27 @@
+/* { dg-do assemble } */
+
+volatile int k = 0;
+
+#define ONE k++;
+#define TEN ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE
+#define HUN TEN TEN TEN TEN TEN TEN TEN TEN TEN TEN
+#define THO HUN HUN HUN HUN HUN HUN HUN HUN HUN HUN
+#define TTH THO THO THO THO THO THO THO THO THO THO THO
+
+void foo (void)
+{
+ start:
+ TTH
+ __asm__ __volatile__ ("" : : : "r28");
+ goto start;
+}
+
+#ifndef __OPTIMIZE__
+void bar (int i)
+{
+ if (i > 0)
+ {
+ TTH
+ }
+}
+#endif
diff --git a/gcc/testsuite/gcc.target/visium/loop_clear.c b/gcc/testsuite/gcc.target/visium/loop_clear.c
new file mode 100644
index 0000000..740e9d2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/visium/loop_clear.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+extern int a[];
+
+void loop_clear (int i)
+{
+ while (i > 0)
+ a[i--] = 0;
+}
+
+/* { dg-final { scan-assembler-times "cmp" 1 { xfail *-*-* } } } */
+
+/* FIXME: the redundant cmp is not eliminated because the compare-elim pass
+ is run before the dbr pass. It's a regression wrt the cc0 port. */
diff --git a/gcc/testsuite/gcc.target/visium/visium.exp b/gcc/testsuite/gcc.target/visium/visium.exp
new file mode 100644
index 0000000..5c179a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/visium/visium.exp
@@ -0,0 +1,44 @@
+# Specific regression driver for Visium.
+# Copyright (C) 2015 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>. */
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't a Visium target.
+if {![istarget visium-*-*] } then {
+ return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
+ "" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gfortran.dg/pointer_init_6.f90 b/gcc/testsuite/gfortran.dg/pointer_init_6.f90
index 428a7de..f5e7555 100644
--- a/gcc/testsuite/gfortran.dg/pointer_init_6.f90
+++ b/gcc/testsuite/gfortran.dg/pointer_init_6.f90
@@ -16,6 +16,7 @@ module m1
integer, pointer :: p2 => p1 ! { dg-error "must have the TARGET attribute" }
integer, pointer :: p3 => x%p ! { dg-error "must have the TARGET attribute" }
integer, pointer :: p4 => x%i
+ integer, pointer :: p5 => u ! { dg-error "has no IMPLICIT type" }
end module m1
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 006bc08..2e23553 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -8754,7 +8754,7 @@ const pass_data pass_data_fixup_cfg =
PROP_cfg, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
- 0, /* todo_flags_start */
+ TODO_update_ssa_only_virtuals, /* todo_flags_start */
0, /* todo_flags_finish */
};
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
index 45ac11e..e7649ef 100644
--- a/gcc/tree-chkp.c
+++ b/gcc/tree-chkp.c
@@ -1686,9 +1686,8 @@ chkp_add_bounds_to_call_stmt (gimple_stmt_iterator *gsi)
&& DECL_FUNCTION_CODE (fndecl) == BUILT_IN_OBJECT_SIZE)
return;
- /* Do nothing for calls to legacy functions. */
- if (fndecl
- && lookup_attribute ("bnd_legacy", DECL_ATTRIBUTES (fndecl)))
+ /* Do nothing for calls to not instrumentable functions. */
+ if (fndecl && !chkp_instrumentable_p (fndecl))
return;
/* Ignore CHKP_INIT_PTR_BOUNDS, CHKP_NULL_PTR_BOUNDS
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 5443ab5..d8abe03 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -3542,7 +3542,7 @@ has_label_address_in_static_1 (tree *nodep, int *walk_subtrees, void *fnp)
/* Determine if the function can be copied. If so return NULL. If
not return a string describng the reason for failure. */
-static const char *
+const char *
copy_forbidden (struct function *fun, tree fndecl)
{
const char *reason = fun->cannot_be_copied_reason;
diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
index 985d83b..f8b2ebf 100644
--- a/gcc/tree-inline.h
+++ b/gcc/tree-inline.h
@@ -234,6 +234,7 @@ extern tree remap_type (tree type, copy_body_data *id);
extern gimple_seq copy_gimple_seq_and_replace_locals (gimple_seq seq);
extern bool debug_find_tree (tree, tree);
extern tree copy_fn (tree, tree&, tree&);
+extern const char *copy_forbidden (struct function *fun, tree fndecl);
/* This is in tree-inline.c since the routine uses
data structures from the inliner. */
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index a4140e5..82d832d 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -2230,6 +2230,8 @@ pass_forwprop::execute (function *fun)
else if (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE
&& gimple_assign_load_p (stmt)
&& !gimple_has_volatile_ops (stmt)
+ && (TREE_CODE (gimple_assign_rhs1 (stmt))
+ != TARGET_MEM_REF)
&& !stmt_can_throw_internal (stmt))
{
/* Rewrite loads used only in real/imagpart extractions to
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index da40088..25aae19 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "diagnostic-core.h"
#include "params.h"
+#include "tree-cfg.h"
/* This implements the pass that does predicate aware warning on uses of
possibly uninitialized variables. The pass first collects the set of
@@ -411,6 +412,7 @@ find_control_equiv_block (basic_block bb)
#define MAX_NUM_CHAINS 8
#define MAX_CHAIN_LEN 5
#define MAX_POSTDOM_CHECK 8
+#define MAX_SWITCH_CASES 40
/* Computes the control dependence chains (paths of edges)
for DEP_BB up to the dominating basic block BB (the head node of a
@@ -592,17 +594,63 @@ convert_control_dep_chain_into_preds (vec<edge> *dep_chains,
if (skip)
continue;
}
- if (gimple_code (cond_stmt) != GIMPLE_COND)
+ if (gimple_code (cond_stmt) == GIMPLE_COND)
+ {
+ one_pred.pred_lhs = gimple_cond_lhs (cond_stmt);
+ one_pred.pred_rhs = gimple_cond_rhs (cond_stmt);
+ one_pred.cond_code = gimple_cond_code (cond_stmt);
+ one_pred.invert = !!(e->flags & EDGE_FALSE_VALUE);
+ t_chain.safe_push (one_pred);
+ has_valid_pred = true;
+ }
+ else if (gswitch *gs = dyn_cast <gswitch *> (cond_stmt))
+ {
+ /* Avoid quadratic behavior. */
+ if (gimple_switch_num_labels (gs) > MAX_SWITCH_CASES)
+ {
+ has_valid_pred = false;
+ break;
+ }
+ /* Find the case label. */
+ tree l = NULL_TREE;
+ unsigned idx;
+ for (idx = 0; idx < gimple_switch_num_labels (gs); ++idx)
+ {
+ tree tl = gimple_switch_label (gs, idx);
+ if (e->dest == label_to_block (CASE_LABEL (tl)))
+ {
+ if (!l)
+ l = tl;
+ else
+ {
+ l = NULL_TREE;
+ break;
+ }
+ }
+ }
+ /* If more than one label reaches this block or the case
+ label doesn't have a single value (like the default one)
+ fail. */
+ if (!l
+ || !CASE_LOW (l)
+ || (CASE_HIGH (l) && !operand_equal_p (CASE_LOW (l),
+ CASE_HIGH (l), 0)))
+ {
+ has_valid_pred = false;
+ break;
+ }
+ one_pred.pred_lhs = gimple_switch_index (gs);
+ one_pred.pred_rhs = CASE_LOW (l);
+ one_pred.cond_code = EQ_EXPR;
+ one_pred.invert = false;
+ t_chain.safe_push (one_pred);
+ has_valid_pred = true;
+ }
+ else
{
has_valid_pred = false;
break;
}
- one_pred.pred_lhs = gimple_cond_lhs (cond_stmt);
- one_pred.pred_rhs = gimple_cond_rhs (cond_stmt);
- one_pred.cond_code = gimple_cond_code (cond_stmt);
- one_pred.invert = !!(e->flags & EDGE_FALSE_VALUE);
- t_chain.safe_push (one_pred);
- has_valid_pred = true;
}
if (!has_valid_pred)
@@ -1329,6 +1377,10 @@ is_pred_expr_subset_of (pred_info expr1, pred_info expr2)
if (expr2.invert)
code2 = invert_tree_comparison (code2, false);
+ if (code1 == EQ_EXPR && code2 == BIT_AND_EXPR)
+ return wi::eq_p (expr1.pred_rhs,
+ wi::bit_and (expr1.pred_rhs, expr2.pred_rhs));
+
if (code1 != code2 && code2 != NE_EXPR)
return false;
@@ -1970,8 +2022,25 @@ normalize_one_pred_1 (pred_chain_union *norm_preds,
}
else if (gimple_assign_rhs_code (def_stmt) == and_or_code)
{
- push_to_worklist (gimple_assign_rhs1 (def_stmt), work_list, mark_set);
- push_to_worklist (gimple_assign_rhs2 (def_stmt), work_list, mark_set);
+ /* Avoid splitting up bit manipulations like x & 3 or y | 1. */
+ if (is_gimple_min_invariant (gimple_assign_rhs2 (def_stmt)))
+ {
+ /* But treat x & 3 as condition. */
+ if (and_or_code == BIT_AND_EXPR)
+ {
+ pred_info n_pred;
+ n_pred.pred_lhs = gimple_assign_rhs1 (def_stmt);
+ n_pred.pred_rhs = gimple_assign_rhs2 (def_stmt);
+ n_pred.cond_code = and_or_code;
+ n_pred.invert = false;
+ norm_chain->safe_push (n_pred);
+ }
+ }
+ else
+ {
+ push_to_worklist (gimple_assign_rhs1 (def_stmt), work_list, mark_set);
+ push_to_worklist (gimple_assign_rhs2 (def_stmt), work_list, mark_set);
+ }
}
else if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))
== tcc_comparison)
diff --git a/libatomic/ChangeLog b/libatomic/ChangeLog
index b0c72d3..ef5b6cd 100644
--- a/libatomic/ChangeLog
+++ b/libatomic/ChangeLog
@@ -1,3 +1,9 @@
+2015-01-16 Ilya Verbin <ilya.verbin@intel.com>
+
+ PR testsuite/64605
+ * testsuite/lib/libatomic.exp: Do not load gcc-dg.exp.
+ * testsuite/libatomic.c/c.exp: Load gcc-dg.exp.
+
2015-01-09 Andreas Tobler <andreast@gcc.gnu.org>
* configure.tgt: Exclude arm*-*-freebsd* from try_ifunc.
diff --git a/libatomic/testsuite/lib/libatomic.exp b/libatomic/testsuite/lib/libatomic.exp
index 28cbaa8..0491c18 100644
--- a/libatomic/testsuite/lib/libatomic.exp
+++ b/libatomic/testsuite/lib/libatomic.exp
@@ -23,6 +23,11 @@ proc load_gcc_lib { filename } {
}
load_lib dg.exp
+
+# Required to use gcc-dg.exp - however, the latter should NOT be
+# loaded until ${tool}_target_compile is defined since it uses that
+# to determine default LTO options.
+
load_gcc_lib file-format.exp
load_gcc_lib target-supports.exp
load_gcc_lib target-utils.exp
@@ -40,7 +45,6 @@ load_gcc_lib torture-options.exp
load_gcc_lib timeout.exp
load_gcc_lib timeout-dg.exp
load_gcc_lib fortran-modules.exp
-load_gcc_lib gcc-dg.exp
set dg-do-what-default run
diff --git a/libatomic/testsuite/libatomic.c/c.exp b/libatomic/testsuite/libatomic.c/c.exp
index 1da3cb1..dbdb5eb 100644
--- a/libatomic/testsuite/libatomic.c/c.exp
+++ b/libatomic/testsuite/libatomic.c/c.exp
@@ -21,6 +21,7 @@ if [info exists lang_test_file] then {
}
load_lib libatomic-dg.exp
+load_gcc_lib gcc-dg.exp
# If a testcase doesn't have special options, use these.
if ![info exists DEFAULT_CFLAGS] then {
diff --git a/libgo/Makefile.am b/libgo/Makefile.am
index 0ce3576..4195981 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -762,6 +762,9 @@ else
if LIBGO_IS_DARWIN
go_net_tcpsockopt_file = go/net/tcpsockopt_darwin.go
else
+if LIBGO_IS_SOLARIS
+go_net_tcpsockopt_file = go/net/tcpsockopt_solaris.go
+else
if LIBGO_IS_DRAGONFLY
go_net_tcpsockopt_file = go/net/tcpsockopt_dragonfly.go
else
@@ -769,6 +772,7 @@ go_net_tcpsockopt_file = go/net/tcpsockopt_unix.go
endif
endif
endif
+endif
go_net_files = \
go/net/cgo_unix.go \
diff --git a/libgo/Makefile.in b/libgo/Makefile.in
index 495dc35..af8566f 100644
--- a/libgo/Makefile.in
+++ b/libgo/Makefile.in
@@ -1019,8 +1019,9 @@ go_mime_files = \
@LIBGO_IS_LINUX_TRUE@go_net_interface_file = go/net/interface_linux.go
@LIBGO_IS_LINUX_FALSE@go_net_cloexec_file = go/net/sys_cloexec.go
@LIBGO_IS_LINUX_TRUE@go_net_cloexec_file = go/net/sock_cloexec.go
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_OPENBSD_FALSE@go_net_tcpsockopt_file = go/net/tcpsockopt_unix.go
-@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_TRUE@@LIBGO_IS_OPENBSD_FALSE@go_net_tcpsockopt_file = go/net/tcpsockopt_dragonfly.go
+@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_tcpsockopt_file = go/net/tcpsockopt_unix.go
+@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_TRUE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_tcpsockopt_file = go/net/tcpsockopt_dragonfly.go
+@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_tcpsockopt_file = go/net/tcpsockopt_solaris.go
@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_OPENBSD_FALSE@go_net_tcpsockopt_file = go/net/tcpsockopt_darwin.go
@LIBGO_IS_OPENBSD_TRUE@go_net_tcpsockopt_file = go/net/tcpsockopt_openbsd.go
go_net_files = \
diff --git a/libgo/go/net/tcpsockopt_solaris.go b/libgo/go/net/tcpsockopt_solaris.go
new file mode 100644
index 0000000..eaab6b6
--- /dev/null
+++ b/libgo/go/net/tcpsockopt_solaris.go
@@ -0,0 +1,27 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TCP socket options for solaris
+
+package net
+
+import (
+ "os"
+ "syscall"
+ "time"
+)
+
+// Set keep alive period.
+func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
+ if err := fd.incref(); err != nil {
+ return err
+ }
+ defer fd.decref()
+
+ // The kernel expects seconds so round to next highest second.
+ d += (time.Second - time.Nanosecond)
+ secs := int(d.Seconds())
+
+ return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.SO_KEEPALIVE, secs))
+}
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 9b003cb..7c106d4 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,7 @@
+2015-01-16 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * target.c (num_devices): Guard with PLUGIN_SUPPORT.
+
2015-01-15 Thomas Schwinge <thomas@codesourcery.com>
James Norris <jnorris@codesourcery.com>
Tom de Vries <tom@codesourcery.com>
diff --git a/libgomp/target.c b/libgomp/target.c
index 83ad511..72d64fc 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -63,8 +63,10 @@ static int num_offload_images;
/* Array of descriptors for all available devices. */
static struct gomp_device_descr *devices;
+#ifdef PLUGIN_SUPPORT
/* Total number of available devices. */
static int num_devices;
+#endif
/* Number of GOMP_OFFLOAD_CAP_OPENMP_400 devices. */
static int num_devices_openmp;
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index df00984..7e68c45 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,28 @@
+2015-01-16 Jonathan Wakely <jwakely@redhat.com>
+
+ * acinclude.m4: Fix typo in comment.
+ * configure: Regenerate.
+ * include/bits/codecvt.h (codecvt<char16_t, char, mbstate_t>,
+ codecvt<char16_t, char, mbstate_t>): Declare specializations.
+ * include/bits/locale_facets.h: Reserve space for new specializations.
+ * src/c++11/Makefile.am: Add codecvt.cc.
+ * src/c++11/Makefile.in: Regenerate.
+ * src/c++11/codecvt.cc: New.
+ * src/c++98/Makefile.am: Compile locale_init.cc and localename.cc
+ with -std=gnu++11.
+ * src/c++98/Makefile.in: Regenerate.
+ * src/c++98/locale_init.cc: Initialize new codecvt specializations.
+ * src/c++98/localename.cc: Likewise.
+ * config/abi/pre/gnu.ver: Exports for new codecvt specializations.
+ * testsuite/22_locale/codecvt/utf8.cc: New.
+ * testsuite/22_locale/locale/cons/unicode.cc: Check that new
+ specializations are installed in locale objects.
+
+2015-01-16 Torvald Riegel <triegel@redhat.com>
+
+ * include/std/shared_mutex (shared_timed_mutex): Add POSIX-based
+ implementation.
+
2015-01-13 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/64571
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index db357d6..74e8eaf 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -1777,7 +1777,7 @@ AC_DEFUN([GLIBCXX_CHECK_C99_TR1], [
<tr1/cinttypes> in namespace std::tr1.])
fi
- # Check for the existence of whcar_t <inttypes.h> functions (NB: doesn't
+ # Check for the existence of wchar_t <inttypes.h> functions (NB: doesn't
# make sense if the glibcxx_cv_c99_stdint_tr1 check fails, per C99, 7.8/1).
ac_c99_inttypes_wchar_t_tr1=no;
if test x"$glibcxx_cv_c99_stdint_tr1" = x"yes"; then
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index 700da18..83f4e8c 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -1759,6 +1759,11 @@ GLIBCXX_3.4.21 {
_ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPK[cw]SC_;
_ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc;
+ # codecvt<char16_t, char, mbstate_t>, codecvt<char32_t, char, mbstate_t>
+ _ZNKSt7codecvtID[is]c11__mbstate_t*;
+ _ZNSt7codecvtID[is]c11__mbstate_t*;
+ _ZT[ISV]St7codecvtID[is]c11__mbstate_tE;
+
} GLIBCXX_3.4.20;
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index be9337fc..7bd1ede 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -19216,7 +19216,7 @@ $as_echo "#define _GLIBCXX_USE_C99_INTTYPES_TR1 1" >>confdefs.h
fi
- # Check for the existence of whcar_t <inttypes.h> functions (NB: doesn't
+ # Check for the existence of wchar_t <inttypes.h> functions (NB: doesn't
# make sense if the glibcxx_cv_c99_stdint_tr1 check fails, per C99, 7.8/1).
ac_c99_inttypes_wchar_t_tr1=no;
if test x"$glibcxx_cv_c99_stdint_tr1" = x"yes"; then
diff --git a/libstdc++-v3/include/bits/codecvt.h b/libstdc++-v3/include/bits/codecvt.h
index 1eee1cc..a6e59b5 100644
--- a/libstdc++-v3/include/bits/codecvt.h
+++ b/libstdc++-v3/include/bits/codecvt.h
@@ -393,7 +393,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
#ifdef _GLIBCXX_USE_WCHAR_T
- /// class codecvt<wchar_t, char, mbstate_t> specialization.
+ /** @brief Class codecvt<wchar_t, char, mbstate_t> specialization.
+ *
+ * Converts between narrow and wide characters in the native character set
+ */
template<>
class codecvt<wchar_t, char, mbstate_t>
: public __codecvt_abstract_base<wchar_t, char, mbstate_t>
@@ -455,6 +458,125 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
#endif //_GLIBCXX_USE_WCHAR_T
+#if __cplusplus >= 201103L
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+ /** @brief Class codecvt<char16_t, char, mbstate_t> specialization.
+ *
+ * Converts between UTF-16 and UTF-8.
+ */
+ template<>
+ class codecvt<char16_t, char, mbstate_t>
+ : public __codecvt_abstract_base<char16_t, char, mbstate_t>
+ {
+ public:
+ // Types:
+ typedef char16_t intern_type;
+ typedef char extern_type;
+ typedef mbstate_t state_type;
+
+ public:
+ static locale::id id;
+
+ explicit
+ codecvt(size_t __refs = 0)
+ : __codecvt_abstract_base<char16_t, char, mbstate_t>(__refs) { }
+
+ protected:
+ virtual
+ ~codecvt();
+
+ virtual result
+ do_out(state_type& __state, const intern_type* __from,
+ const intern_type* __from_end, const intern_type*& __from_next,
+ extern_type* __to, extern_type* __to_end,
+ extern_type*& __to_next) const;
+
+ virtual result
+ do_unshift(state_type& __state,
+ extern_type* __to, extern_type* __to_end,
+ extern_type*& __to_next) const;
+
+ virtual result
+ do_in(state_type& __state,
+ const extern_type* __from, const extern_type* __from_end,
+ const extern_type*& __from_next,
+ intern_type* __to, intern_type* __to_end,
+ intern_type*& __to_next) const;
+
+ virtual
+ int do_encoding() const throw();
+
+ virtual
+ bool do_always_noconv() const throw();
+
+ virtual
+ int do_length(state_type&, const extern_type* __from,
+ const extern_type* __end, size_t __max) const;
+
+ virtual int
+ do_max_length() const throw();
+ };
+
+ /** @brief Class codecvt<char32_t, char, mbstate_t> specialization.
+ *
+ * Converts between UTF-32 and UTF-8.
+ */
+ template<>
+ class codecvt<char32_t, char, mbstate_t>
+ : public __codecvt_abstract_base<char32_t, char, mbstate_t>
+ {
+ public:
+ // Types:
+ typedef char32_t intern_type;
+ typedef char extern_type;
+ typedef mbstate_t state_type;
+
+ public:
+ static locale::id id;
+
+ explicit
+ codecvt(size_t __refs = 0)
+ : __codecvt_abstract_base<char32_t, char, mbstate_t>(__refs) { }
+
+ protected:
+ virtual
+ ~codecvt();
+
+ virtual result
+ do_out(state_type& __state, const intern_type* __from,
+ const intern_type* __from_end, const intern_type*& __from_next,
+ extern_type* __to, extern_type* __to_end,
+ extern_type*& __to_next) const;
+
+ virtual result
+ do_unshift(state_type& __state,
+ extern_type* __to, extern_type* __to_end,
+ extern_type*& __to_next) const;
+
+ virtual result
+ do_in(state_type& __state,
+ const extern_type* __from, const extern_type* __from_end,
+ const extern_type*& __from_next,
+ intern_type* __to, intern_type* __to_end,
+ intern_type*& __to_next) const;
+
+ virtual
+ int do_encoding() const throw();
+
+ virtual
+ bool do_always_noconv() const throw();
+
+ virtual
+ int do_length(state_type&, const extern_type* __from,
+ const extern_type* __end, size_t __max) const;
+
+ virtual int
+ do_max_length() const throw();
+ };
+
+#endif // _GLIBCXX_USE_C99_STDINT_TR1
+#endif // C++11
+
/// class codecvt_byname [22.2.1.6].
template<typename _InternT, typename _ExternT, typename _StateT>
class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT>
diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h
index a5fc45e..77932a5 100644
--- a/libstdc++-v3/include/bits/locale_facets.h
+++ b/libstdc++-v3/include/bits/locale_facets.h
@@ -59,6 +59,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
# define _GLIBCXX_NUM_FACETS 14
# define _GLIBCXX_NUM_CXX11_FACETS 8
#endif
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+# define _GLIBCXX_NUM_UNICODE_FACETS 2
+#else
+# define _GLIBCXX_NUM_UNICODE_FACETS 0
+#endif
// Convert string to numeric value of type _Tp and store results.
// NB: This is specialized for all required types, there is no
diff --git a/libstdc++-v3/include/std/shared_mutex b/libstdc++-v3/include/std/shared_mutex
index 8bfede3..643768c 100644
--- a/libstdc++-v3/include/std/shared_mutex
+++ b/libstdc++-v3/include/std/shared_mutex
@@ -57,6 +57,188 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// shared_timed_mutex
class shared_timed_mutex
{
+#if defined(__GTHREADS_CXX0X)
+ typedef chrono::system_clock __clock_t;
+
+ pthread_rwlock_t _M_rwlock;
+
+ public:
+ shared_timed_mutex()
+ {
+ int __ret = pthread_rwlock_init(&_M_rwlock, NULL);
+ if (__ret == ENOMEM)
+ throw bad_alloc();
+ else if (__ret == EAGAIN)
+ __throw_system_error(int(errc::resource_unavailable_try_again));
+ else if (__ret == EPERM)
+ __throw_system_error(int(errc::operation_not_permitted));
+ // Errors not handled: EBUSY, EINVAL
+ _GLIBCXX_DEBUG_ASSERT(__ret == 0);
+ }
+
+ ~shared_timed_mutex()
+ {
+ int __ret __attribute((unused)) = pthread_rwlock_destroy(&_M_rwlock);
+ // Errors not handled: EBUSY, EINVAL
+ _GLIBCXX_DEBUG_ASSERT(__ret == 0);
+ }
+
+ shared_timed_mutex(const shared_timed_mutex&) = delete;
+ shared_timed_mutex& operator=(const shared_timed_mutex&) = delete;
+
+ // Exclusive ownership
+
+ void
+ lock()
+ {
+ int __ret = pthread_rwlock_wrlock(&_M_rwlock);
+ if (__ret == EDEADLK)
+ __throw_system_error(int(errc::resource_deadlock_would_occur));
+ // Errors not handled: EINVAL
+ _GLIBCXX_DEBUG_ASSERT(__ret == 0);
+ }
+
+ bool
+ try_lock()
+ {
+ int __ret = pthread_rwlock_trywrlock(&_M_rwlock);
+ if (__ret == EBUSY) return false;
+ // Errors not handled: EINVAL
+ _GLIBCXX_DEBUG_ASSERT(__ret == 0);
+ return true;
+ }
+
+ template<typename _Rep, typename _Period>
+ bool
+ try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time)
+ {
+ return try_lock_until(__clock_t::now() + __rel_time);
+ }
+
+ template<typename _Duration>
+ bool
+ try_lock_until(const chrono::time_point<__clock_t, _Duration>& __atime)
+ {
+ auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
+ auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
+
+ __gthread_time_t __ts =
+ {
+ static_cast<std::time_t>(__s.time_since_epoch().count()),
+ static_cast<long>(__ns.count())
+ };
+
+ int __ret = pthread_rwlock_timedwrlock(&_M_rwlock, &__ts);
+ // On self-deadlock, we just fail to acquire the lock. Technically,
+ // the program violated the precondition.
+ if (__ret == ETIMEDOUT || __ret == EDEADLK)
+ return false;
+ // Errors not handled: EINVAL
+ _GLIBCXX_DEBUG_ASSERT(__ret == 0);
+ return true;
+ }
+
+ template<typename _Clock, typename _Duration>
+ bool
+ try_lock_until(const chrono::time_point<_Clock, _Duration>& __abs_time)
+ {
+ // DR 887 - Sync unknown clock to known clock.
+ const typename _Clock::time_point __c_entry = _Clock::now();
+ const __clock_t::time_point __s_entry = __clock_t::now();
+ const auto __delta = __abs_time - __c_entry;
+ const auto __s_atime = __s_entry + __delta;
+ return try_lock_until(__s_atime);
+ }
+
+ void
+ unlock()
+ {
+ int __ret __attribute((unused)) = pthread_rwlock_unlock(&_M_rwlock);
+ // Errors not handled: EPERM, EBUSY, EINVAL
+ _GLIBCXX_DEBUG_ASSERT(__ret == 0);
+ }
+
+ // Shared ownership
+
+ void
+ lock_shared()
+ {
+ int __ret = pthread_rwlock_rdlock(&_M_rwlock);
+ if (__ret == EDEADLK)
+ __throw_system_error(int(errc::resource_deadlock_would_occur));
+ if (__ret == EAGAIN)
+ // Maximum number of read locks has been exceeded.
+ __throw_system_error(int(errc::device_or_resource_busy));
+ // Errors not handled: EINVAL
+ _GLIBCXX_DEBUG_ASSERT(__ret == 0);
+ }
+
+ bool
+ try_lock_shared()
+ {
+ int __ret = pthread_rwlock_tryrdlock(&_M_rwlock);
+ // If the maximum number of read locks has been exceeded, we just fail
+ // to acquire the lock. Unlike for lock(), we are not allowed to throw
+ // an exception.
+ if (__ret == EBUSY || __ret == EAGAIN) return false;
+ // Errors not handled: EINVAL
+ _GLIBCXX_DEBUG_ASSERT(__ret == 0);
+ return true;
+ }
+
+ template<typename _Rep, typename _Period>
+ bool
+ try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time)
+ {
+ return try_lock_shared_until(__clock_t::now() + __rel_time);
+ }
+
+ template<typename _Duration>
+ bool
+ try_lock_shared_until(const chrono::time_point<__clock_t,
+ _Duration>& __atime)
+ {
+ auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
+ auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
+
+ __gthread_time_t __ts =
+ {
+ static_cast<std::time_t>(__s.time_since_epoch().count()),
+ static_cast<long>(__ns.count())
+ };
+
+ int __ret = pthread_rwlock_timedrdlock(&_M_rwlock, &__ts);
+ // If the maximum number of read locks has been exceeded, or we would
+ // deadlock, we just fail to acquire the lock. Unlike for lock(),
+ // we are not allowed to throw an exception.
+ if (__ret == ETIMEDOUT || __ret == EAGAIN || __ret == EDEADLK)
+ return false;
+ // Errors not handled: EINVAL
+ _GLIBCXX_DEBUG_ASSERT(__ret == 0);
+ return true;
+ }
+
+ template<typename _Clock, typename _Duration>
+ bool
+ try_lock_shared_until(const chrono::time_point<_Clock,
+ _Duration>& __abs_time)
+ {
+ // DR 887 - Sync unknown clock to known clock.
+ const typename _Clock::time_point __c_entry = _Clock::now();
+ const __clock_t::time_point __s_entry = __clock_t::now();
+ const auto __delta = __abs_time - __c_entry;
+ const auto __s_atime = __s_entry + __delta;
+ return try_lock_shared_until(__s_atime);
+ }
+
+ void
+ unlock_shared()
+ {
+ unlock();
+ }
+
+#else // defined(__GTHREADS_CXX0X)
+
#if _GTHREAD_USE_MUTEX_TIMEDLOCK
struct _Mutex : mutex, __timed_mutex_impl<_Mutex>
{
@@ -252,6 +434,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_gate1.notify_one();
}
}
+#endif // !defined(__GTHREADS_CXX0X)
};
#endif // _GLIBCXX_HAS_GTHREADS
diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am
index 4cba983..b57e552 100644
--- a/libstdc++-v3/src/c++11/Makefile.am
+++ b/libstdc++-v3/src/c++11/Makefile.am
@@ -53,6 +53,7 @@ endif
sources = \
chrono.cc \
+ codecvt.cc \
condition_variable.cc \
cow-stdexcept.cc \
ctype.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in
index 619bf37..00a5c25 100644
--- a/libstdc++-v3/src/c++11/Makefile.in
+++ b/libstdc++-v3/src/c++11/Makefile.in
@@ -72,12 +72,12 @@ libc__11convenience_la_LIBADD =
@ENABLE_DUAL_ABI_TRUE@ cxx11-ios_failure.lo \
@ENABLE_DUAL_ABI_TRUE@ cxx11-shim_facets.lo cxx11-stdexcept.lo
am__objects_2 = ctype_configure_char.lo ctype_members.lo
-am__objects_3 = chrono.lo condition_variable.lo cow-stdexcept.lo \
- ctype.lo debug.lo functexcept.lo functional.lo future.lo \
- hash_c++0x.lo hashtable_c++0x.lo ios.lo limits.lo mutex.lo \
- placeholders.lo random.lo regex.lo shared_ptr.lo \
- snprintf_lite.lo system_error.lo thread.lo $(am__objects_1) \
- $(am__objects_2)
+am__objects_3 = chrono.lo codecvt.lo condition_variable.lo \
+ cow-stdexcept.lo ctype.lo debug.lo functexcept.lo \
+ functional.lo future.lo hash_c++0x.lo hashtable_c++0x.lo \
+ ios.lo limits.lo mutex.lo placeholders.lo random.lo regex.lo \
+ shared_ptr.lo snprintf_lite.lo system_error.lo thread.lo \
+ $(am__objects_1) $(am__objects_2)
@ENABLE_DUAL_ABI_TRUE@am__objects_4 = cow-fstream-inst.lo \
@ENABLE_DUAL_ABI_TRUE@ cow-sstream-inst.lo cow-string-inst.lo \
@ENABLE_DUAL_ABI_TRUE@ cow-wstring-inst.lo cxx11-locale-inst.lo \
@@ -344,6 +344,7 @@ host_sources = \
sources = \
chrono.cc \
+ codecvt.cc \
condition_variable.cc \
cow-stdexcept.cc \
ctype.cc \
diff --git a/libstdc++-v3/src/c++11/codecvt.cc b/libstdc++-v3/src/c++11/codecvt.cc
new file mode 100644
index 0000000..fdd4972
--- /dev/null
+++ b/libstdc++-v3/src/c++11/codecvt.cc
@@ -0,0 +1,461 @@
+// Locale support (codecvt) -*- C++ -*-
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+#include <bits/locale_classes.h>
+#include <bits/codecvt.h>
+#include <bits/stl_algobase.h> // std::max
+#include <cstring> // std::memcpy, std::memcmp
+
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+namespace
+{
+ // Largest code point that fits in a single UTF-16 code unit.
+ const char32_t max_single_utf16_unit = 0xFFFF;
+ const char32_t max_code_point = 0x10FFFF;
+
+ template<typename Elem>
+ struct range
+ {
+ Elem* next;
+ Elem* end;
+
+ Elem operator*() const { return *next; }
+
+ range& operator++() { ++next; return *this; }
+
+ size_t size() const { return end - next; }
+ };
+
+ char32_t
+ read_utf8_code_point(range<const char>& from, unsigned long maxcode)
+ {
+ size_t avail = from.size();
+ if (avail == 0)
+ return -1;
+ unsigned char c1 = from.next[0];
+ // https://en.wikipedia.org/wiki/UTF-8#Sample_code
+ if (c1 < 0x80)
+ {
+ ++from.next;
+ return c1;
+ }
+ else if (c1 < 0xC2) // continuation or overlong 2-byte sequence
+ return -1;
+ else if (c1 < 0xE0) // 2-byte sequence
+ {
+ if (avail < 2)
+ return -1;
+ unsigned char c2 = from.next[1];
+ if ((c2 & 0xC0) != 0x80)
+ return -1;
+ char32_t c = (c1 << 6) + c2 - 0x3080;
+ if (c > maxcode)
+ return -1;
+ from.next += 2;
+ return c;
+ }
+ else if (c1 < 0xF0) // 3-byte sequence
+ {
+ if (avail < 3)
+ return -1;
+ unsigned char c2 = from.next[1];
+ if ((c2 & 0xC0) != 0x80)
+ return -1;
+ if (c1 == 0xE0 && c2 < 0xA0) // overlong
+ return -1;
+ unsigned char c3 = from.next[2];
+ if ((c3 & 0xC0) != 0x80)
+ return -1;
+ char32_t c = (c1 << 12) + (c2 << 6) + c3 - 0xE2080;
+ if (c > maxcode)
+ return -1;
+ from.next += 3;
+ return c;
+ }
+ else if (c1 < 0xF5) // 4-byte sequence
+ {
+ if (avail < 4)
+ return -1;
+ unsigned char c2 = from.next[1];
+ if ((c2 & 0xC0) != 0x80)
+ return -1;
+ if (c1 == 0xF0 && c2 < 0x90) // overlong
+ return -1;
+ if (c1 == 0xF4 && c2 >= 0x90) // > U+10FFFF
+ return -1;
+ unsigned char c3 = from.next[2];
+ if ((c3 & 0xC0) != 0x80)
+ return -1;
+ unsigned char c4 = from.next[3];
+ if ((c4 & 0xC0) != 0x80)
+ return -1;
+ char32_t c = (c1 << 18) + (c2 << 12) + (c3 << 6) + c4 - 0x3C82080;
+ if (c > maxcode)
+ return -1;
+ from.next += 4;
+ return c;
+ }
+ else // > U+10FFFF
+ return -1;
+ }
+
+ bool
+ write_utf8_code_point(range<char>& to, char32_t code_point)
+ {
+ if (code_point < 0x80)
+ {
+ if (to.size() < 1)
+ return false;
+ *to.next++ = code_point;
+ }
+ else if (code_point <= 0x7FF)
+ {
+ if (to.size() < 2)
+ return false;
+ *to.next++ = (code_point >> 6) + 0xC0;
+ *to.next++ = (code_point & 0x3F) + 0x80;
+ }
+ else if (code_point <= 0xFFFF)
+ {
+ if (to.size() < 3)
+ return false;
+ *to.next++ = (code_point >> 12) + 0xE0;
+ *to.next++ = ((code_point >> 6) & 0x3F) + 0x80;
+ *to.next++ = (code_point & 0x3F) + 0x80;
+ }
+ else if (code_point <= 0x10FFFF)
+ {
+ if (to.size() < 4)
+ return false;
+ *to.next++ = (code_point >> 18) + 0xF0;
+ *to.next++ = ((code_point >> 12) & 0x3F) + 0x80;
+ *to.next++ = ((code_point >> 6) & 0x3F) + 0x80;
+ *to.next++ = (code_point & 0x3F) + 0x80;
+ }
+ else
+ return false;
+ return true;
+ }
+
+ bool
+ write_utf16_code_point(range<char16_t>& to, char32_t codepoint)
+ {
+ if (codepoint < max_single_utf16_unit)
+ {
+ if (to.size() > 0)
+ {
+ *to.next = codepoint;
+ ++to.next;
+ return true;
+ }
+ }
+ else if (to.size() > 1)
+ {
+ // Algorithm from http://www.unicode.org/faq/utf_bom.html#utf16-4
+ const char32_t LEAD_OFFSET = 0xD800 - (0x10000 >> 10);
+ const char32_t SURROGATE_OFFSET = 0x10000 - (0xD800 << 10) - 0xDC00;
+ char16_t lead = LEAD_OFFSET + (codepoint >> 10);
+ char16_t trail = 0xDC00 + (codepoint & 0x3FF);
+ char32_t utf16bytes = (lead << 10) + trail + SURROGATE_OFFSET;
+
+ to.next[0] = utf16bytes >> 16;
+ to.next[1] = utf16bytes & 0xFFFF;
+ to.next += 2;
+ return true;
+ }
+ return false;
+ }
+
+ // utf8 -> ucs4
+ codecvt_base::result
+ ucs4_in(range<const char>& from, range<char32_t>& to,
+ unsigned long maxcode = max_code_point)
+ {
+ while (from.size() && to.size())
+ {
+ const char32_t codepoint = read_utf8_code_point(from, maxcode);
+ if (codepoint == char32_t(-1) || codepoint > maxcode)
+ return codecvt_base::error;
+ *to.next++ = codepoint;
+ }
+ return from.size() ? codecvt_base::partial : codecvt_base::ok;
+ }
+
+ // ucs4 -> utf8
+ codecvt_base::result
+ ucs4_out(range<const char32_t>& from, range<char>& to,
+ unsigned long maxcode = max_code_point)
+ {
+ while (from.size())
+ {
+ const char32_t c = from.next[0];
+ if (c > maxcode)
+ return codecvt_base::error;
+ if (!write_utf8_code_point(to, c))
+ return codecvt_base::partial;
+ ++from.next;
+ }
+ return codecvt_base::ok;
+ }
+
+ // utf8 -> utf16
+ codecvt_base::result
+ utf16_in(range<const char>& from, range<char16_t>& to,
+ unsigned long maxcode = max_code_point)
+ {
+ while (from.size() && to.size())
+ {
+ const char* first = from.next;
+ if ((unsigned char)*first >= 0xF0 && to.size() < 2)
+ return codecvt_base::partial;
+ const char32_t codepoint = read_utf8_code_point(from, maxcode);
+ if (codepoint == char32_t(-1) || codepoint > maxcode)
+ return codecvt_base::error;
+ if (!write_utf16_code_point(to, codepoint))
+ {
+ from.next = first;
+ return codecvt_base::partial;
+ }
+ }
+ return codecvt_base::ok;
+ }
+
+ // utf16 -> utf8
+ codecvt_base::result
+ utf16_out(range<const char16_t>& from, range<char>& to,
+ unsigned long maxcode = max_code_point)
+ {
+ while (from.size())
+ {
+ char32_t c = from.next[0];
+ int inc = 1;
+ if (c >= 0xD800 && c < 0xDBFF) // start of surrogate pair
+ {
+ if (from.size() < 2)
+ return codecvt_base::ok; // stop converting at this point
+
+ const char32_t c2 = from.next[1];
+ if (c2 >= 0xDC00 && c2 <= 0xDFFF)
+ {
+ inc = 2;
+ c = (c << 10) + c2 - 0x35FDC00;
+ }
+ else
+ return codecvt_base::error;
+ }
+ if (c > maxcode)
+ return codecvt_base::error;
+ if (!write_utf8_code_point(to, c))
+ return codecvt_base::partial;
+ from.next += inc;
+ }
+ return codecvt_base::ok;
+ }
+
+ // return pos such that [begin,pos) is valid UTF-16 string no longer than max
+ int
+ utf16_len(const char* begin, const char* end, size_t max,
+ char32_t maxcode = max_code_point)
+ {
+ range<const char> from{ begin, end };
+ size_t count = 0;
+ while (count+1 < max)
+ {
+ char32_t c = read_utf8_code_point(from, maxcode);
+ if (c == char32_t(-1))
+ break;
+ else if (c > max_single_utf16_unit)
+ ++count;
+ ++count;
+ }
+ if (count+1 == max) // take one more character if it fits in a single unit
+ read_utf8_code_point(from, std::max(max_single_utf16_unit, maxcode));
+ return from.next - begin;
+ }
+
+ // return pos such that [begin,pos) is valid UCS-4 string no longer than max
+ int
+ ucs4_len(const char* begin, const char* end, size_t max,
+ char32_t maxcode = max_code_point)
+ {
+ range<const char> from{ begin, end };
+ size_t count = 0;
+ while (count < max)
+ {
+ char32_t c = read_utf8_code_point(from, maxcode);
+ if (c == char32_t(-1))
+ break;
+ ++count;
+ }
+ return from.next - begin;
+ }
+}
+
+// Define members of codecvt<char16_t, char, mbstate_t> specialization.
+// Converts from UTF-8 to UTF-16.
+
+locale::id codecvt<char16_t, char, mbstate_t>::id;
+
+codecvt<char16_t, char, mbstate_t>::~codecvt() { }
+
+codecvt_base::result
+codecvt<char16_t, char, mbstate_t>::
+do_out(state_type&,
+ const intern_type* __from,
+ const intern_type* __from_end, const intern_type*& __from_next,
+ extern_type* __to, extern_type* __to_end,
+ extern_type*& __to_next) const
+{
+ range<const char16_t> from{ __from, __from_end };
+ range<char> to{ __to, __to_end };
+ auto res = utf16_out(from, to);
+ __from_next = from.next;
+ __to_next = to.next;
+ return res;
+}
+
+codecvt_base::result
+codecvt<char16_t, char, mbstate_t>::
+do_unshift(state_type&, extern_type* __to, extern_type*,
+ extern_type*& __to_next) const
+{
+ __to_next = __to;
+ return noconv; // we don't use mbstate_t for the unicode facets
+}
+
+codecvt_base::result
+codecvt<char16_t, char, mbstate_t>::
+do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
+ const extern_type*& __from_next,
+ intern_type* __to, intern_type* __to_end,
+ intern_type*& __to_next) const
+{
+ range<const char> from{ __from, __from_end };
+ range<char16_t> to{ __to, __to_end };
+ auto res = utf16_in(from, to);
+ __from_next = from.next;
+ __to_next = to.next;
+ return res;
+}
+
+int
+codecvt<char16_t, char, mbstate_t>::do_encoding() const throw()
+{ return 0; }
+
+bool
+codecvt<char16_t, char, mbstate_t>::do_always_noconv() const throw()
+{ return false; }
+
+int
+codecvt<char16_t, char, mbstate_t>::
+do_length(state_type&, const extern_type* __from,
+ const extern_type* __end, size_t __max) const
+{
+ return utf16_len(__from, __end, __max);
+}
+
+int
+codecvt<char16_t, char, mbstate_t>::do_max_length() const throw()
+{
+ // Any valid UTF-8 sequence of 3 bytes fits in a single 16-bit code unit,
+ // whereas 4 byte sequences require two 16-bit code units.
+ return 3;
+}
+
+// Define members of codecvt<char32_t, char, mbstate_t> specialization.
+// Converts from UTF-8 to UTF-32 (aka UCS-4).
+
+locale::id codecvt<char32_t, char, mbstate_t>::id;
+
+codecvt<char32_t, char, mbstate_t>::~codecvt() { }
+
+codecvt_base::result
+codecvt<char32_t, char, mbstate_t>::
+do_out(state_type&, const intern_type* __from, const intern_type* __from_end,
+ const intern_type*& __from_next,
+ extern_type* __to, extern_type* __to_end,
+ extern_type*& __to_next) const
+{
+ range<const char32_t> from{ __from, __from_end };
+ range<char> to{ __to, __to_end };
+ auto res = ucs4_out(from, to);
+ __from_next = from.next;
+ __to_next = to.next;
+ return res;
+}
+
+codecvt_base::result
+codecvt<char32_t, char, mbstate_t>::
+do_unshift(state_type&, extern_type* __to, extern_type*,
+ extern_type*& __to_next) const
+{
+ __to_next = __to;
+ return noconv;
+}
+
+codecvt_base::result
+codecvt<char32_t, char, mbstate_t>::
+do_in(state_type&, const extern_type* __from, const extern_type* __from_end,
+ const extern_type*& __from_next,
+ intern_type* __to, intern_type* __to_end,
+ intern_type*& __to_next) const
+{
+ range<const char> from{ __from, __from_end };
+ range<char32_t> to{ __to, __to_end };
+ auto res = ucs4_in(from, to);
+ __from_next = from.next;
+ __to_next = to.next;
+ return res;
+}
+
+int
+codecvt<char32_t, char, mbstate_t>::do_encoding() const throw()
+{ return 0; }
+
+bool
+codecvt<char32_t, char, mbstate_t>::do_always_noconv() const throw()
+{ return false; }
+
+int
+codecvt<char32_t, char, mbstate_t>::
+do_length(state_type&, const extern_type* __from,
+ const extern_type* __end, size_t __max) const
+{
+ return ucs4_len(__from, __end, __max);
+}
+
+int
+codecvt<char32_t, char, mbstate_t>::do_max_length() const throw()
+{ return 4; }
+
+inline template class __codecvt_abstract_base<char16_t, char, mbstate_t>;
+inline template class __codecvt_abstract_base<char32_t, char, mbstate_t>;
+
+_GLIBCXX_END_NAMESPACE_VERSION
+}
+#endif // _GLIBCXX_USE_C99_STDINT_TR1
diff --git a/libstdc++-v3/src/c++98/Makefile.am b/libstdc++-v3/src/c++98/Makefile.am
index 6dd7a72..e348dfb 100644
--- a/libstdc++-v3/src/c++98/Makefile.am
+++ b/libstdc++-v3/src/c++98/Makefile.am
@@ -176,6 +176,16 @@ numeric_members_cow.o: numeric_members_cow.cc
$(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $<
endif
+# XXX TODO move locale_init.cc and localename.cc to src/c++11
+locale_init.lo: locale_init.cc
+ $(LTCXXCOMPILE) -std=gnu++11 -c $<
+locale_init.o: locale_init.cc
+ $(LTCXXCOMPILE) -std=gnu++11 -c $<
+localename.lo: localename.cc
+ $(LTCXXCOMPILE) -std=gnu++11 -c $<
+localename.o: localename.cc
+ $(LTCXXCOMPILE) -std=gnu++11 -c $<
+
# Use special rules for the deprecated source files so that they find
# deprecated include files.
GLIBCXX_INCLUDE_DIR=$(glibcxx_builddir)/include
diff --git a/libstdc++-v3/src/c++98/Makefile.in b/libstdc++-v3/src/c++98/Makefile.in
index 9a2a27f..3c69791 100644
--- a/libstdc++-v3/src/c++98/Makefile.in
+++ b/libstdc++-v3/src/c++98/Makefile.in
@@ -764,6 +764,16 @@ vpath % $(top_srcdir)/src/c++98
@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $<
@ENABLE_DUAL_ABI_TRUE@numeric_members_cow.o: numeric_members_cow.cc
@ENABLE_DUAL_ABI_TRUE@ $(CXXCOMPILE) $(GLIBCXX_ABI_FLAGS) -fimplicit-templates -c $<
+
+# XXX TODO move locale_init.cc and localename.cc to src/c++11
+locale_init.lo: locale_init.cc
+ $(LTCXXCOMPILE) -std=gnu++11 -c $<
+locale_init.o: locale_init.cc
+ $(LTCXXCOMPILE) -std=gnu++11 -c $<
+localename.lo: localename.cc
+ $(LTCXXCOMPILE) -std=gnu++11 -c $<
+localename.o: localename.cc
+ $(LTCXXCOMPILE) -std=gnu++11 -c $<
strstream.lo: strstream.cc
$(LTCXXCOMPILE) -I$(GLIBCXX_INCLUDE_DIR)/backward -Wno-deprecated -c $<
strstream.o: strstream.cc
diff --git a/libstdc++-v3/src/c++98/locale_init.cc b/libstdc++-v3/src/c++98/locale_init.cc
index c45eff3..0a95b9f 100644
--- a/libstdc++-v3/src/c++98/locale_init.cc
+++ b/libstdc++-v3/src/c++98/locale_init.cc
@@ -57,7 +57,7 @@ _GLIBCXX_LOC_ID(_ZNSt8messagesIwE2idE);
namespace
{
- const int num_facets = _GLIBCXX_NUM_FACETS
+ const int num_facets = _GLIBCXX_NUM_FACETS + _GLIBCXX_NUM_UNICODE_FACETS
+ (_GLIBCXX_USE_DUAL_ABI ? _GLIBCXX_NUM_CXX11_FACETS : 0);
__gnu_cxx::__mutex&
@@ -201,6 +201,16 @@ namespace
fake_messages_w messages_w;
#endif
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+ typedef char fake_codecvt_c16[sizeof(codecvt<char16_t, char, mbstate_t>)]
+ __attribute__ ((aligned(__alignof__(codecvt<char16_t, char, mbstate_t>))));
+ fake_codecvt_c16 codecvt_c16;
+
+ typedef char fake_codecvt_c32[sizeof(codecvt<char32_t, char, mbstate_t>)]
+ __attribute__ ((aligned(__alignof__(codecvt<char32_t, char, mbstate_t>))));
+ fake_codecvt_c32 codecvt_c32;
+#endif
+
// Storage for "C" locale caches.
typedef char fake_num_cache_c[sizeof(std::__numpunct_cache<char>)]
__attribute__ ((aligned(__alignof__(std::__numpunct_cache<char>))));
@@ -319,6 +329,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
&std::ctype<wchar_t>::id,
&codecvt<wchar_t, char, mbstate_t>::id,
#endif
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+ &codecvt<char16_t, char, mbstate_t>::id,
+ &codecvt<char32_t, char, mbstate_t>::id,
+#endif
0
};
@@ -522,6 +536,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_init_facet(new (&messages_w) std::messages<wchar_t>(1));
#endif
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+ _M_init_facet(new (&codecvt_c16) codecvt<char16_t, char, mbstate_t>(1));
+ _M_init_facet(new (&codecvt_c32) codecvt<char32_t, char, mbstate_t>(1));
+#endif
+
#if _GLIBCXX_USE_DUAL_ABI
facet* extra[] = { __npc, __mpcf, __mpct
# ifdef _GLIBCXX_USE_WCHAR_T
diff --git a/libstdc++-v3/src/c++98/localename.cc b/libstdc++-v3/src/c++98/localename.cc
index c42a217..2884bee 100644
--- a/libstdc++-v3/src/c++98/localename.cc
+++ b/libstdc++-v3/src/c++98/localename.cc
@@ -171,7 +171,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
-const int num_facets = _GLIBCXX_NUM_FACETS
+const int num_facets = _GLIBCXX_NUM_FACETS + _GLIBCXX_NUM_UNICODE_FACETS
+ (_GLIBCXX_USE_DUAL_ABI ? _GLIBCXX_NUM_CXX11_FACETS : 0);
// Construct named _Impl.
@@ -267,7 +267,12 @@ const int num_facets = _GLIBCXX_NUM_FACETS
_M_init_facet(new time_get<wchar_t>);
_M_init_facet(new time_put<wchar_t>);
_M_init_facet(new std::messages<wchar_t>(__cloc, __s));
-#endif
+#endif
+
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+ _M_init_facet(new codecvt<char16_t, char, mbstate_t>);
+ _M_init_facet(new codecvt<char32_t, char, mbstate_t>);
+#endif
#if _GLIBCXX_USE_DUAL_ABI
_M_init_extra(&__cloc, &__clocm, __s, __smon);
diff --git a/libstdc++-v3/testsuite/22_locale/codecvt/utf8.cc b/libstdc++-v3/testsuite/22_locale/codecvt/utf8.cc
new file mode 100644
index 0000000..987233a
--- /dev/null
+++ b/libstdc++-v3/testsuite/22_locale/codecvt/utf8.cc
@@ -0,0 +1,76 @@
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-require-cstdint "" }
+// { dg-options "-std=gnu++11" }
+
+#include <locale>
+#include <iterator>
+#include <string>
+#include <testsuite_hooks.h>
+
+const char expected[] = u8"£¥€";
+const std::size_t expected_len = std::char_traits<char>::length(expected);
+
+template<typename C>
+void test(const C* from)
+{
+ auto len = std::char_traits<C>::length(from);
+ std::mbstate_t state{};
+ char buf[16] = { };
+ using test_type = std::codecvt<C, char, std::mbstate_t>;
+ const test_type& cvt = std::use_facet<test_type>(std::locale::classic());
+ auto from_end = from + len;
+ auto from_next = from;
+ auto buf_end = std::end(buf);
+ auto buf_next = buf;
+ auto res = cvt.out(state, from, from_end, from_next, buf, buf_end, buf_next);
+ VERIFY( res == std::codecvt_base::ok );
+ VERIFY( from_next == from_end );
+ VERIFY( (buf_next - buf) == expected_len );
+ VERIFY( 0 == std::char_traits<char>::compare(buf, expected, expected_len) );
+
+ C buf2[16];
+ auto exp_end = expected + expected_len;
+ auto exp_next = expected;
+ auto buf2_end = std::end(buf2);
+ auto buf2_next = buf2;
+ res = cvt.in(state, expected, exp_end, exp_next, buf2, buf2_end, buf2_next);
+ VERIFY( res == std::codecvt_base::ok );
+ VERIFY( exp_next == exp_end );
+ VERIFY( (buf2_next - buf2) == len );
+ VERIFY( 0 == std::char_traits<C>::compare(buf2, from, len) );
+}
+
+void
+test01()
+{
+ test(u"£¥€");
+}
+
+void
+test02()
+{
+ test(U"£¥€");
+}
+
+int
+main()
+{
+ test01();
+ test02();
+}
diff --git a/libstdc++-v3/testsuite/22_locale/locale/cons/unicode.cc b/libstdc++-v3/testsuite/22_locale/locale/cons/unicode.cc
index b6f8c8b..33b5a8a 100644
--- a/libstdc++-v3/testsuite/22_locale/locale/cons/unicode.cc
+++ b/libstdc++-v3/testsuite/22_locale/locale/cons/unicode.cc
@@ -1,4 +1,5 @@
// { dg-require-iconv "ISO-8859-1" }
+// { dg-options "-std=gnu++11" }
// Copyright (C) 2006-2015 Free Software Foundation, Inc.
//
@@ -32,6 +33,11 @@ typedef std::codecvt<char, char, std::mbstate_t> c_codecvt;
typedef std::codecvt<wchar_t, char, std::mbstate_t> w_codecvt;
#endif
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+typedef std::codecvt<char16_t, char, std::mbstate_t> u16_codecvt;
+typedef std::codecvt<char32_t, char, std::mbstate_t> u32_codecvt;
+#endif
+
class gnu_facet: public std::locale::facet
{
public:
@@ -61,6 +67,10 @@ void test01()
#ifdef _GLIBCXX_USE_WCHAR_T
VERIFY( has_facet<w_codecvt>(loc13) );
#endif
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
+ VERIFY( has_facet<u16_codecvt>(loc13) );
+ VERIFY( has_facet<u32_codecvt>(loc13) );
+#endif
VERIFY( has_facet<unicode_codecvt>(loc13) );
}
catch(...)