diff options
author | David Edelsohn <dje.gcc@gmail.com> | 2014-01-11 18:57:56 +0000 |
---|---|---|
committer | David Edelsohn <dje@gcc.gnu.org> | 2014-01-11 13:57:56 -0500 |
commit | c82846bc44d259ea1702410f916ff3c0aa019f7b (patch) | |
tree | a5436871a1c494bc86f3e27e8561dc3c69eeb824 | |
parent | 2558e2e838790ef1441788c0ba4c14e1bf061b55 (diff) | |
download | gcc-c82846bc44d259ea1702410f916ff3c0aa019f7b.zip gcc-c82846bc44d259ea1702410f916ff3c0aa019f7b.tar.gz gcc-c82846bc44d259ea1702410f916ff3c0aa019f7b.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000-builtin.def | 8 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 78 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 3 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 16 |
5 files changed, 117 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a66a01d..7b38804 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2014-01-11 David Edelsohn <dje.gcc@gmail.com> + + 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 <bin.cheng@arm.com> * 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 4d25bfd..b7b67fa 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 500acb7..e4daa78 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 @@ -11469,6 +11470,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) { rtx pat; @@ -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 fdbe965..1a37a5d 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 f9f988b..744a11d 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 ]) @@ -15587,6 +15589,20 @@ }) +(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 ;; register that is being loaded. The fused ops must be physically adjacent. |