diff options
author | Christian Bruel <christian.bruel@st.com> | 2014-07-02 15:03:14 +0200 |
---|---|---|
committer | Christian Bruel <chrbr@gcc.gnu.org> | 2014-07-02 15:03:14 +0200 |
commit | cbb1e3d98c5f18f82c1b733aa6338fab78fb891b (patch) | |
tree | d5f4efb38c4b5345b26af85c0f13b1a9412dd461 /gcc/config/sh | |
parent | b18f1efce09e8cab57d6141754db3456fab938f7 (diff) | |
download | gcc-cbb1e3d98c5f18f82c1b733aa6338fab78fb891b.zip gcc-cbb1e3d98c5f18f82c1b733aa6338fab78fb891b.tar.gz gcc-cbb1e3d98c5f18f82c1b733aa6338fab78fb891b.tar.bz2 |
Support mode toggle.
* mode-switching.c (struct bb_info): Add mode_out, mode_in caches.
(make_preds_opaque): Delete.
(clear_mode_bit, mode_bit_p, set_mode_bit): New macros.
(commit_mode_sets): New function.
(optimize_mode_switching): Handle current_mode to mode_switching_emit.
Process all modes at once.
* basic-block.h (pre_edge_lcm_avs): Declare.
* lcm.c (pre_edge_lcm_avs): Renamed from pre_edge_lcm.
Call clear_aux_for_edges. Fix comments.
(pre_edge_lcm): New wrapper function to call pre_edge_lcm_avs.
(pre_edge_rev_lcm): Idem.
* config/epiphany/epiphany.c (emit_set_fp_mode): Add prev_mode parameter.
* config/epiphany/epiphany-protos.h (emit_set_fp_mode): Idem.
* config/epiphany/resolve-sw-modes.c (pass_resolve_sw_modes::execute): Idem.
* config/i386/i386.c (x96_emit_mode_set): Idem.
* config/sh/sh.c (sh_emit_mode_set): Likewise. Handle PR toggle.
* config/sh/sh.md (toggle_pr): Defined if TARGET_FPU_SINGLE.
(fpscr_toggle) Disallow from delay slot.
* target.def (emit_mode_set): Add prev_mode parameter.
* doc/tm.texi: Regenerate.
From-SVN: r212230
Diffstat (limited to 'gcc/config/sh')
-rw-r--r-- | gcc/config/sh/sh.c | 14 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 10 |
2 files changed, 15 insertions, 9 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index ac157e4..02468da 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -203,7 +203,7 @@ static void push_regs (HARD_REG_SET *, int); static int calc_live_regs (HARD_REG_SET *); static HOST_WIDE_INT rounded_frame_size (int); static bool sh_frame_pointer_required (void); -static void sh_emit_mode_set (int, int, HARD_REG_SET); +static void sh_emit_mode_set (int, int, int, HARD_REG_SET); static int sh_mode_needed (int, rtx); static int sh_mode_after (int, int, rtx); static int sh_mode_entry (int); @@ -13583,9 +13583,17 @@ sh_try_omit_signzero_extend (rtx extended_op, rtx insn) static void sh_emit_mode_set (int entity ATTRIBUTE_UNUSED, int mode, - HARD_REG_SET regs_live) + int prev_mode, HARD_REG_SET regs_live) { - fpscr_set_from_mem (mode, regs_live); + if ((TARGET_SH4A_FP || TARGET_SH4_300) + && prev_mode != FP_MODE_NONE && prev_mode != mode) + { + emit_insn (gen_toggle_pr ()); + if (TARGET_FMOVD) + emit_insn (gen_toggle_sz ()); + } + else + fpscr_set_from_mem (mode, regs_live); } static int diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index d998af9..b5d05f4 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -504,6 +504,7 @@ (define_attr "in_delay_slot" "yes,no" (cond [(eq_attr "type" "cbranch") (const_string "no") (eq_attr "type" "pcload,pcload_si") (const_string "no") + (eq_attr "type" "fpscr_toggle") (const_string "no") (eq_attr "needs_delay_slot" "yes") (const_string "no") (eq_attr "length" "2") (const_string "yes") ] (const_string "no"))) @@ -12239,15 +12240,12 @@ label: "fschg" [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")]) -;; There's no way we can use it today, since optimize mode switching -;; doesn't enable us to know from which mode we're switching to the -;; mode it requests, to tell whether we can use a relative mode switch -;; (like toggle_pr) or an absolute switch (like loading fpscr from -;; memory). +;; Toggle FPU precision PR mode. + (define_insn "toggle_pr" [(set (reg:PSI FPSCR_REG) (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))] - "TARGET_SH4A_FP && ! TARGET_FPU_SINGLE" + "TARGET_SH4A_FP" "fpchg" [(set_attr "type" "fpscr_toggle")]) |