From: David Edelsohn Date: Sat, 11 Jan 2014 18:57:56 +0000 (+0000) Subject: re PR target/58115 (testcase gcc.target/i386/intrinsics_4.c failure) X-Git-Tag: releases/gcc-4.9.0~1701 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c82846bc44d259ea1702410f916ff3c0aa019f7b;p=thirdparty%2Fgcc.git re PR target/58115 (testcase gcc.target/i386/intrinsics_4.c failure) PR target/58115 * config/rs6000/rs6000.h (SWITCHABLE_TARGET): Define. * config/rs6000/rs6000.c: Include target-globals.h. (rs6000_set_current_function): Instead of doing target_reinit unconditionally, use save_target_globals_default_opts and restore_target_globals. * config/rs6000/rs6000-builtin.def (mffs, mtfsf): Add builtins for FPSCR. * config/rs6000/rs6000.c (rs6000_expand_mtfsf_builtin): New. (rs6000_expand_builtin): Handle mffs and mtfsf. (rs6000_init_builtins): Define mffs and mtfsf. * config/rs6000/rs6000.md (UNSPECV_MFFS, UNSPECV_MTFSF): New. (rs6000_mffs): New pattern. (rs6000_mtfsf): New pattern. From-SVN: r206554 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a66a01d05e71..7b38804c3eda 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2014-01-11 David Edelsohn + + PR target/58115 + * config/rs6000/rs6000.h (SWITCHABLE_TARGET): Define. + * config/rs6000/rs6000.c: Include target-globals.h. + (rs6000_set_current_function): Instead of doing target_reinit + unconditionally, use save_target_globals_default_opts and + restore_target_globals. + + * config/rs6000/rs6000-builtin.def (mffs, mtfsf): Add builtins for + FPSCR. + * config/rs6000/rs6000.c (rs6000_expand_mtfsf_builtin): New. + (rs6000_expand_builtin): Handle mffs and mtfsf. + (rs6000_init_builtins): Define mffs and mtfsf. + * config/rs6000/rs6000.md (UNSPECV_MFFS, UNSPECV_MTFSF): New constants. + (rs6000_mffs): New pattern. + (rs6000_mtfsf): New pattern. + 2014-01-11 Bin Cheng * tree-ssa-loop-ivopts.c (iv_ca_narrow): New parameter. diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def index 4d25bfd6534a..b7b67fae1c8f 100644 --- a/gcc/config/rs6000/rs6000-builtin.def +++ b/gcc/config/rs6000/rs6000-builtin.def @@ -1752,6 +1752,14 @@ BU_SPECIAL_X (RS6000_BUILTIN_GET_TB, "__builtin_ppc_get_timebase", BU_SPECIAL_X (RS6000_BUILTIN_MFTB, "__builtin_ppc_mftb", RS6000_BTM_ALWAYS, RS6000_BTC_MISC) +BU_SPECIAL_X (RS6000_BUILTIN_MFFS, "__builtin_mffs", + RS6000_BTM_ALWAYS, RS6000_BTC_MISC) + +RS6000_BUILTIN_X (RS6000_BUILTIN_MTFSF, "__builtin_mtfsf", + RS6000_BTM_ALWAYS, + RS6000_BTC_MISC | RS6000_BTC_UNARY | RS6000_BTC_VOID, + CODE_FOR_rs6000_mtfsf) + /* Darwin CfString builtin. */ BU_SPECIAL_X (RS6000_BUILTIN_CFSTRING, "__builtin_cfstring", RS6000_BTM_ALWAYS, RS6000_BTC_MISC) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 500acb7d762e..e4daa789f402 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -78,6 +78,7 @@ #include "tree-vectorizer.h" #include "dumpfile.h" #include "cgraph.h" +#include "target-globals.h" #if TARGET_XCOFF #include "xcoffout.h" /* get declarations of xcoff_*_section_name */ #endif @@ -11468,6 +11469,48 @@ rs6000_expand_zeroop_builtin (enum insn_code icode, rtx target) } +static rtx +rs6000_expand_mtfsf_builtin (enum insn_code icode, tree exp, rtx target) +{ + rtx pat; + tree arg0 = CALL_EXPR_ARG (exp, 0); + tree arg1 = CALL_EXPR_ARG (exp, 1); + rtx op0 = expand_normal (arg0); + rtx op1 = expand_normal (arg1); + enum machine_mode mode0 = insn_data[icode].operand[0].mode; + enum machine_mode mode1 = insn_data[icode].operand[1].mode; + + if (icode == CODE_FOR_nothing) + /* Builtin not supported on this processor. */ + return 0; + + /* If we got invalid arguments bail out before generating bad rtl. */ + if (arg0 == error_mark_node || arg1 == error_mark_node) + return const0_rtx; + + if (GET_CODE (op0) != CONST_INT + || INTVAL (op0) > 255 + || INTVAL (op0) < 0) + { + error ("argument 1 must be an 8-bit field value"); + return const0_rtx; + } + + if (! (*insn_data[icode].operand[0].predicate) (op0, mode0)) + op0 = copy_to_mode_reg (mode0, op0); + + if (! (*insn_data[icode].operand[1].predicate) (op1, mode1)) + op1 = copy_to_mode_reg (mode1, op1); + + pat = GEN_FCN (icode) (op0, op1); + if (! pat) + return const0_rtx; + emit_insn (pat); + + return NULL_RTX; +} + + static rtx rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target) { @@ -13277,6 +13320,12 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, : CODE_FOR_rs6000_mftb_si), target); + case RS6000_BUILTIN_MFFS: + return rs6000_expand_zeroop_builtin (CODE_FOR_rs6000_mffs, target); + + case RS6000_BUILTIN_MTFSF: + return rs6000_expand_mtfsf_builtin (CODE_FOR_rs6000_mtfsf, exp, target); + case ALTIVEC_BUILTIN_MASK_FOR_LOAD: case ALTIVEC_BUILTIN_MASK_FOR_STORE: { @@ -13584,6 +13633,14 @@ rs6000_init_builtins (void) NULL_TREE); def_builtin ("__builtin_ppc_mftb", ftype, RS6000_BUILTIN_MFTB); + ftype = build_function_type_list (double_type_node, NULL_TREE); + def_builtin ("__builtin_mffs", ftype, RS6000_BUILTIN_MFFS); + + ftype = build_function_type_list (void_type_node, + intSI_type_node, double_type_node, + NULL_TREE); + def_builtin ("__builtin_mtfsf", ftype, RS6000_BUILTIN_MTFSF); + #if TARGET_XCOFF /* AIX libm provides clog as __clog. */ if ((tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE) @@ -31199,16 +31256,25 @@ rs6000_set_current_function (tree fndecl) { cl_target_option_restore (&global_options, TREE_TARGET_OPTION (new_tree)); - target_reinit (); + if (TREE_TARGET_GLOBALS (new_tree)) + restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); + else + TREE_TARGET_GLOBALS (new_tree) + = save_target_globals_default_opts (); } else if (old_tree) { - struct cl_target_option *def - = TREE_TARGET_OPTION (target_option_current_node); - - cl_target_option_restore (&global_options, def); - target_reinit (); + new_tree = target_option_current_node; + cl_target_option_restore (&global_options, + TREE_TARGET_OPTION (new_tree)); + if (TREE_TARGET_GLOBALS (new_tree)) + restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); + else if (new_tree == target_option_default_node) + restore_target_globals (&default_target_globals); + else + TREE_TARGET_GLOBALS (new_tree) + = save_target_globals_default_opts (); } } } diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index fdbe965ec023..1a37a5df981a 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -2446,6 +2446,9 @@ extern char rs6000_reg_names[][8]; /* register names (0 vs. %r0). */ #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR) +/* For switching between functions with different target attributes. */ +#define SWITCHABLE_TARGET 1 + /* uncomment for disabling the corresponding default options */ /* #define MACHINE_no_sched_interblock */ /* #define MACHINE_no_sched_speculative */ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index f9f988bca1f8..744a11d6d969 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -140,6 +140,8 @@ UNSPECV_ISYNC ; isync instruction UNSPECV_MFTB ; move from time base UNSPECV_NLGR ; non-local goto receiver + UNSPECV_MFFS ; Move from FPSCR + UNSPECV_MTFSF ; Move to FPSCR Fields ]) @@ -15586,6 +15588,20 @@ return "mftb %0"; }) + +(define_insn "rs6000_mffs" + [(set (match_operand:DF 0 "gpc_reg_operand" "=d") + (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))] + "TARGET_HARD_FLOAT && TARGET_FPRS" + "mffs %0") + +(define_insn "rs6000_mtfsf" + [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i") + (match_operand:DF 1 "gpc_reg_operand" "d")] + UNSPECV_MTFSF)] + "TARGET_HARD_FLOAT && TARGET_FPRS" + "mtfsf %0,%1") + ;; Power8 fusion support for fusing an addis instruction with a D-form load of ;; a GPR. The addis instruction must be adjacent to the load, and use the same