diff options
author | Oleg Endo <olegendo@gcc.gnu.org> | 2014-10-18 10:51:08 +0000 |
---|---|---|
committer | Oleg Endo <olegendo@gcc.gnu.org> | 2014-10-18 10:51:08 +0000 |
commit | fe3e478fb1bf55dd6be3f708f3f90478dd6d1e39 (patch) | |
tree | ceddd0f8598d93825e1843a5627012d331c1cadf | |
parent | 7e813472a20d496c4dafb20a704932656bfc8366 (diff) | |
download | gcc-fe3e478fb1bf55dd6be3f708f3f90478dd6d1e39.tar.gz |
re PR target/53513 ([SH] Add support for fpchg insn and improve fenv support)
gcc/
PR target/53513
* config/sh/sh-modes.def (PSI): Remove.
* config/sh/sh-protos.h (get_fpscr_rtx): Remove.
* config/sh/sh.c (fpscr_rtx, get_fpscr_rtx): Remove.
(sh_reorg): Remove commented out FPSCR code.
(fpscr_set_from_mem): Use SImode instead of PSImode. Emit lds_fpscr
insn instead of move insn.
(sh_hard_regno_mode_ok): Return SImode for FPSCR.
(sh_legitimate_address_p, sh_legitimize_reload_address): Remove PSImode
handling.
(sh_emit_mode_set): Emit lds_fpscr and sts_fpscr insns.
(sh1_builtin_p): Uncomment.
(SH_BLTIN_UV 25, SH_BLTIN_VU 26): New macros.
(bdesc): Add __builtin_sh_get_fpscr and __builtin_sh_set_fpscr.
* config/sh/sh/predicates.md (fpscr_operand): Simplify.
(fpscr_movsrc_operand, fpscr_movdst_operand): New predicates.
(general_movsrc_operand, general_movdst_operand): Disallow
fpscr_operand.
* config/sh/sh.md (FPSCR_FR): New constant.
(push_fpscr): Emit sts_fpscr insn.
(pop_fpscr): Emit lds_fpscr_insn.
(movsi_ie): Disallow FPSCR operands.
(fpu_switch, unnamed related split, extend_psi_si,
truncate_si_psi): Remove insns.
(lds_fpscr, sts_fpscr): New insns.
(toggle_sz, toggle_pr): Use SImode for FPSCR_REG instead of PSImode.
From-SVN: r216424
-rw-r--r-- | gcc/ChangeLog | 29 | ||||
-rw-r--r-- | gcc/config/sh/predicates.md | 34 | ||||
-rw-r--r-- | gcc/config/sh/sh-modes.def | 2 | ||||
-rw-r--r-- | gcc/config/sh/sh-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/sh/sh.c | 70 | ||||
-rw-r--r-- | gcc/config/sh/sh.md | 165 |
6 files changed, 147 insertions, 155 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b2a8e7a2a6f..74037a227f2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,32 @@ +2014-10-18 Oleg Endo <olegendo@gcc.gnu.org> + + PR target/53513 + * config/sh/sh-modes.def (PSI): Remove. + * config/sh/sh-protos.h (get_fpscr_rtx): Remove. + * config/sh/sh.c (fpscr_rtx, get_fpscr_rtx): Remove. + (sh_reorg): Remove commented out FPSCR code. + (fpscr_set_from_mem): Use SImode instead of PSImode. Emit lds_fpscr + insn instead of move insn. + (sh_hard_regno_mode_ok): Return SImode for FPSCR. + (sh_legitimate_address_p, sh_legitimize_reload_address): Remove PSImode + handling. + (sh_emit_mode_set): Emit lds_fpscr and sts_fpscr insns. + (sh1_builtin_p): Uncomment. + (SH_BLTIN_UV 25, SH_BLTIN_VU 26): New macros. + (bdesc): Add __builtin_sh_get_fpscr and __builtin_sh_set_fpscr. + * config/sh/sh/predicates.md (fpscr_operand): Simplify. + (fpscr_movsrc_operand, fpscr_movdst_operand): New predicates. + (general_movsrc_operand, general_movdst_operand): Disallow + fpscr_operand. + * config/sh/sh.md (FPSCR_FR): New constant. + (push_fpscr): Emit sts_fpscr insn. + (pop_fpscr): Emit lds_fpscr_insn. + (movsi_ie): Disallow FPSCR operands. + (fpu_switch, unnamed related split, extend_psi_si, + truncate_si_psi): Remove insns. + (lds_fpscr, sts_fpscr): New insns. + (toggle_sz, toggle_pr): Use SImode for FPSCR_REG instead of PSImode. + 2014-10-17 Eric Botcazou <ebotcazou@adacore.com> * ipa-inline-transform.c (master_clone_with_noninline_clones_p): New. diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md index e15388b3fba..ff1c2f54a38 100644 --- a/gcc/config/sh/predicates.md +++ b/gcc/config/sh/predicates.md @@ -154,7 +154,7 @@ return (regno != T_REG && regno != PR_REG && ! TARGET_REGISTER_P (regno) - && regno != FPUL_REG + && regno != FPUL_REG && regno != FPSCR_REG && regno != MACH_REG && regno != MACL_REG); } /* Allow a no-op sign extension - compare LOAD_EXTEND_OP. @@ -347,13 +347,27 @@ ;; Returns true if OP is the FPSCR. (define_predicate "fpscr_operand" - (match_code "reg") + (and (match_code "reg") + (match_test "REGNO (op) == FPSCR_REG"))) + +;; Returns true if OP is a valid source operand for a FPSCR move insn. +(define_predicate "fpscr_movsrc_operand" + (match_code "reg,subreg,mem") { - return (REG_P (op) - && (REGNO (op) == FPSCR_REG - || (REGNO (op) >= FIRST_PSEUDO_REGISTER - && !(reload_in_progress || reload_completed))) - && GET_MODE (op) == PSImode); + if (arith_reg_operand (op, mode)) + return true; + + return MEM_P (op) && GET_CODE (XEXP (op, 0)) == POST_INC; +}) + +;; Returns true if OP is a valid destination operand for a FPSCR move insn. +(define_predicate "fpscr_movdst_operand" + (match_code "reg,subreg,mem") +{ + if (arith_reg_dest (op, mode)) + return true; + + return MEM_P (op) && GET_CODE (XEXP (op, 0)) == PRE_DEC; }) ;; Returns true if OP is an operand that is either the fpul hard reg or @@ -451,6 +465,9 @@ if (t_reg_operand (op, mode)) return 0; + if (fpscr_operand (op, mode)) + return false; + /* Disallow PC relative QImode loads, since these is no insn to do that and an imm8 load should be used instead. */ if (IS_PC_RELATIVE_LOAD_ADDR_P (op) && GET_MODE (op) == QImode) @@ -546,6 +563,9 @@ if (t_reg_operand (op, mode)) return 0; + if (fpscr_operand (op, mode)) + return false; + if (MEM_P (op)) { rtx inside = XEXP (op, 0); diff --git a/gcc/config/sh/sh-modes.def b/gcc/config/sh/sh-modes.def index 3aa3046e37f..02710aa29e4 100644 --- a/gcc/config/sh/sh-modes.def +++ b/gcc/config/sh/sh-modes.def @@ -17,8 +17,6 @@ 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/>. */ -/* The SH uses a partial integer mode to represent the FPSCR register. */ -PARTIAL_INT_MODE (SI, 22, PSI); /* PDI mode is used to represent a function address in a target register. */ PARTIAL_INT_MODE (DI, 64, PDI); diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h index ca007b9093c..77c9ae4e342 100644 --- a/gcc/config/sh/sh-protos.h +++ b/gcc/config/sh/sh-protos.h @@ -107,7 +107,6 @@ extern int barrier_align (rtx_insn *); extern int sh_loop_align (rtx_insn *); extern bool fp_zero_operand (rtx); extern bool fp_one_operand (rtx); -extern rtx get_fpscr_rtx (void); extern bool sh_legitimate_index_p (enum machine_mode, rtx, bool, bool); extern bool sh_legitimize_reload_address (rtx *, enum machine_mode, int, int); extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx); @@ -185,7 +184,6 @@ extern void sh_cpu_cpp_builtins (cpp_reader* pfile); extern const char *output_jump_label_table (void); extern rtx get_t_reg_rtx (void); -extern rtx get_fpscr_rtx (void); extern int sh_media_register_for_return (void); extern void sh_expand_prologue (void); extern void sh_expand_epilogue (bool); diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 7433476601d..3daa375b957 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -6443,14 +6443,6 @@ sh_reorg (void) emit_insn_before (gen_use_sfunc_addr (reg), insn); } } -#if 0 - /* fpscr is not actually a user variable, but we pretend it is for the - sake of the previous optimization passes, since we want it handled like - one. However, we don't have any debugging information for it, so turn - it into a non-user variable now. */ - if (TARGET_SH4) - REG_USERVAR_P (get_fpscr_rtx ()) = 0; -#endif mdep_reorg_phase = SH_AFTER_MDEP_REORG; } @@ -10009,21 +10001,6 @@ get_t_reg_rtx (void) return t_reg_rtx; } -static GTY(()) rtx fpscr_rtx; -rtx -get_fpscr_rtx (void) -{ - if (! fpscr_rtx) - { - fpscr_rtx = gen_rtx_REG (PSImode, FPSCR_REG); - REG_USERVAR_P (fpscr_rtx) = 1; - mark_user_reg (fpscr_rtx); - } - if (! reload_completed || mdep_reorg_phase != SH_AFTER_MDEP_REORG) - mark_user_reg (fpscr_rtx); - return fpscr_rtx; -} - static GTY(()) tree fpscr_values; static void @@ -10055,13 +10032,12 @@ emit_fpu_switch (rtx scratch, int index) emit_move_insn (scratch, XEXP (src, 0)); if (index != 0) emit_insn (gen_addsi3 (scratch, scratch, GEN_INT (index * 4))); - src = adjust_automodify_address (src, PSImode, scratch, index * 4); + src = adjust_automodify_address (src, SImode, scratch, index * 4); } else - src = adjust_address (src, PSImode, index * 4); + src = adjust_address (src, SImode, index * 4); - dst = get_fpscr_rtx (); - emit_move_insn (dst, src); + emit_insn (gen_lds_fpscr (src)); } static rtx get_free_reg (HARD_REG_SET); @@ -10269,8 +10245,7 @@ sh_legitimate_address_p (enum machine_mode mode, rtx x, bool strict) && ! TARGET_SHMEDIA && MAYBE_BASE_REGISTER_RTX_P (XEXP (x, 0), strict)) return true; - else if (GET_CODE (x) == PLUS - && (mode != PSImode || reload_completed)) + else if (GET_CODE (x) == PLUS) { rtx xop0 = XEXP (x, 0); rtx xop1 = XEXP (x, 1); @@ -10474,7 +10449,6 @@ sh_legitimize_address (rtx x, rtx oldx, enum machine_mode mode) return gen_rtx_PLUS (Pmode, sum, adj.mov_disp); } } - return x; } @@ -10516,7 +10490,6 @@ sh_legitimize_reload_address (rtx *p, enum machine_mode mode, int opnum, if (GET_CODE (*p) == PLUS && CONST_INT_P (XEXP (*p, 1)) && MAYBE_BASE_REGISTER_RTX_P (XEXP (*p, 0), true) - && ! (mode == PSImode && type == RELOAD_FOR_INPUT_ADDRESS) && (ALLOW_INDEXED_ADDRESS || XEXP (*p, 0) == stack_pointer_rtx || XEXP (*p, 0) == hard_frame_pointer_rtx)) @@ -11607,13 +11580,12 @@ shmedia_builtin_p (void) } /* This function can be used if there are any built-ins that are not for - SHmedia. It's commented out to avoid the defined-but-unused warning. + SHmedia. It's commented out to avoid the defined-but-unused warning. */ static bool sh1_builtin_p (void) { return TARGET_SH1; } -*/ /* describe number and signedness of arguments; arg[0] == result (1: unsigned, 2: signed, 4: don't care, 8: pointer 0: no argument */ @@ -11674,6 +11646,10 @@ static const char signature_args[][4] = { 0, 8 }, #define SH_BLTIN_VP 24 { 8, 0 }, +#define SH_BLTIN_UV 25 + { 1, 0 }, +#define SH_BLTIN_VU 26 + { 0, 1 }, }; /* mcmv: operands considered unsigned. */ /* mmulsum_wq, msad_ubq: result considered unsigned long long. */ @@ -11849,6 +11825,11 @@ static struct builtin_description bdesc[] = CODE_FOR_byterev, "__builtin_sh_media_BYTEREV", SH_BLTIN_2, 0 }, { shmedia_builtin_p, CODE_FOR_prefetch, "__builtin_sh_media_PREFO", SH_BLTIN_PSSV, 0 }, + + { sh1_builtin_p, + CODE_FOR_sts_fpscr, "__builtin_sh_get_fpscr", SH_BLTIN_UV, 0 }, + { sh1_builtin_p, + CODE_FOR_set_fpscr, "__builtin_sh_set_fpscr", SH_BLTIN_VU, 0 }, }; static void @@ -12162,7 +12143,7 @@ sh_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode) return mode == SImode; if (regno == FPSCR_REG) - return mode == PSImode; + return mode == SImode; /* FIXME. This works around PR target/37633 for -O0. */ if (!optimize && TARGET_SHMEDIA32 && GET_MODE_SIZE (mode) > 4) @@ -13627,33 +13608,24 @@ sh_emit_mode_set (int entity ATTRIBUTE_UNUSED, int mode, } else if (mode != FP_MODE_NONE) { - rtx tmp0 = gen_reg_rtx (PSImode); - rtx tmp1 = gen_reg_rtx (SImode); - - emit_move_insn (tmp0, get_fpscr_rtx ()); - emit_insn (gen_extend_psi_si (tmp1, tmp0)); - + rtx tmp = gen_reg_rtx (SImode); + emit_insn (gen_sts_fpscr (tmp)); rtx i = NULL; const unsigned HOST_WIDE_INT fpbits = TARGET_FMOVD ? (FPSCR_PR | FPSCR_SZ) : FPSCR_PR; if (prev_mode != FP_MODE_NONE && prev_mode != mode) - i = gen_xorsi3 (tmp1, tmp1, - force_reg (SImode, GEN_INT (fpbits))); + i = gen_xorsi3 (tmp, tmp, force_reg (SImode, GEN_INT (fpbits))); else if (mode == FP_MODE_SINGLE) - i = gen_andsi3 (tmp1, tmp1, - force_reg (SImode, GEN_INT (~fpbits))); + i = gen_andsi3 (tmp, tmp, force_reg (SImode, GEN_INT (~fpbits))); else if (mode == FP_MODE_DOUBLE) - i = gen_iorsi3 (tmp1, tmp1, - force_reg (SImode, GEN_INT (fpbits))); + i = gen_iorsi3 (tmp, tmp, force_reg (SImode, GEN_INT (fpbits))); else gcc_unreachable (); emit_insn (i); - - emit_insn (gen_truncate_si_psi (tmp0, tmp1)); - emit_move_insn (get_fpscr_rtx (), tmp0); + emit_insn (gen_lds_fpscr (tmp)); } } diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index e77e3aeeb79..675017c2c97 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -116,8 +116,9 @@ (XD0_REG 136) - (FPSCR_PR 524288) - (FPSCR_SZ 1048576) + (FPSCR_PR 524288) ;; 1 << 19 + (FPSCR_SZ 1048576) ;; 1 << 20 + (FPSCR_FR 2097152) ;; 1 << 21 ]) (define_c_enum "unspec" [ @@ -6508,11 +6509,11 @@ label: [(const_int 0)] "TARGET_SH2E" { - rtx insn = emit_insn (gen_fpu_switch (gen_frame_mem (PSImode, - gen_rtx_PRE_DEC (Pmode, - stack_pointer_rtx)), - get_fpscr_rtx ())); - add_reg_note (insn, REG_INC, stack_pointer_rtx); + add_reg_note ( + emit_insn ( + gen_sts_fpscr ( + gen_frame_mem (SImode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx)))), + REG_INC, stack_pointer_rtx); DONE; }) @@ -6520,11 +6521,11 @@ label: [(const_int 0)] "TARGET_SH2E" { - rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (), - gen_frame_mem (PSImode, - gen_rtx_POST_INC (Pmode, - stack_pointer_rtx)))); - add_reg_note (insn, REG_INC, stack_pointer_rtx); + add_reg_note ( + emit_insn ( + gen_lds_fpscr ( + gen_frame_mem (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx)))), + REG_INC, stack_pointer_rtx); DONE; }) @@ -6713,8 +6714,10 @@ label: (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,I20,I28,mr,x,l,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))] "(TARGET_SH2E || TARGET_SH2A) - && (register_operand (operands[0], SImode) - || register_operand (operands[1], SImode))" + && ((register_operand (operands[0], SImode) + && !fpscr_operand (operands[0], SImode)) + || (register_operand (operands[1], SImode) + && !fpscr_operand (operands[1], SImode)))" "@ mov.l %1,%0 mov %1,%0 @@ -12207,97 +12210,69 @@ label: ;; Floating point instructions. ;; ------------------------------------------------------------------------- -;; ??? All patterns should have a type attribute. - -(define_expand "movpsi" - [(set (match_operand:PSI 0 "register_operand" "") - (match_operand:PSI 1 "general_movsrc_operand" ""))] - "TARGET_FPU_ANY" -{ - emit_insn (gen_fpu_switch (operands[0], operands[1])); - DONE; -}) - -;; The c / m alternative is a fake to guide reload to load directly into -;; fpscr, since reload doesn't know how to use post-increment. -;; TARGET_LEGITIMATE_ADDRESS_P guards about bogus addresses before reload, -;; SECONDARY_INPUT_RELOAD_CLASS does this during reload, and the insn's -;; predicate after reload. -;; The mac_gp type for r/!c might look a bit odd, but it actually schedules -;; like a mac -> gpr move. -(define_insn "fpu_switch" - [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<") - (match_operand:PSI 1 "general_movsrc_operand" " c,>,m,m,r,r,r,!c,c")) - (use (reg:SI FPSCR_STAT_REG)) - (use (reg:SI FPSCR_MODES_REG)) +;; FIXME: For now we disallow any memory operands for fpscr loads/stores, +;; except for post-inc loads and pre-dec stores for push/pop purposes. +;; This avoids problems with reload. As a consequence, user initiated fpscr +;; stores to memory will always be ferried through a general register. +;; User initiated fpscr loads always have to undergo bit masking to preserve +;; the current fpu mode settings for the compiler generated code. Thus such +;; fpscr loads will always have to go through general registers anyways. +(define_insn "lds_fpscr" + [(set (reg:SI FPSCR_REG) + (match_operand:SI 0 "fpscr_movsrc_operand" "r,>")) (set (reg:SI FPSCR_STAT_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_STAT)) (set (reg:SI FPSCR_MODES_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))] - "TARGET_FPU_ANY - && (! reload_completed - || true_regnum (operands[0]) != FPSCR_REG - || !MEM_P (operands[1]) - || GET_CODE (XEXP (operands[1], 0)) != PLUS)" + "TARGET_FPU_ANY" + "@ + lds %0,fpscr + lds.l %0,fpscr" + [(set_attr "type" "gp_fpscr,mem_fpscr")]) + +;; A move fpscr -> reg schedules like a move mac -> reg. Thus we use mac_gp +;; type for it. +(define_insn "sts_fpscr" + [(set (match_operand:SI 0 "fpscr_movdst_operand" "=r,<") + (reg:SI FPSCR_REG)) + (use (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] + "TARGET_FPU_ANY" "@ - ! precision stays the same - lds.l %1,fpscr - mov.l %1,%0 - # - lds %1,fpscr - mov %1,%0 - mov.l %1,%0 sts fpscr,%0 sts.l fpscr,%0" - [(set_attr "length" "0,2,2,4,2,2,2,2,2") - (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store, - mac_gp,fstore")]) + [(set_attr "type" "mac_gp,fstore")]) -(define_split - [(set (reg:PSI FPSCR_REG) - (match_operand:PSI 0 "simple_mem_operand")) - (use (reg:SI FPSCR_STAT_REG)) - (use (reg:SI FPSCR_MODES_REG)) - (set (reg:SI FPSCR_STAT_REG) - (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_STAT)) - (set (reg:SI FPSCR_MODES_REG) - (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))] - "TARGET_FPU_ANY && reload_completed" - [(const_int 0)] +(define_expand "set_fpscr" + [(parallel [(set (reg:SI FPSCR_REG) + (match_operand:SI 0 "general_operand")) + (set (reg:SI FPSCR_STAT_REG) + (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))])] + "TARGET_FPU_ANY" { - rtx addrreg = XEXP (operands[0], 0); - rtx mem = replace_equiv_address (operands[0], - gen_rtx_POST_INC (Pmode, addrreg)); + /* We have to mask out the FR, SZ and PR bits. To do that, we need to + get the current FPSCR value first. + (a & ~mask) | (b & mask) = a ^ ((a ^ b) & mask) */ - add_reg_note (emit_insn (gen_fpu_switch (get_fpscr_rtx (), mem)), - REG_INC, addrreg); + rtx mask = force_reg (SImode, GEN_INT (FPSCR_FR | FPSCR_SZ | FPSCR_PR)); - /* Modify the address reg to compensate for the forced post-inc mode. - If the address reg becomes dead afterwards, the add will be eliminated - automatically. */ - emit_insn (gen_addsi3 (addrreg, addrreg, GEN_INT (-4))); -}) + rtx a = force_reg (SImode, operands[0]); -;; The 'extend_psi_si' and 'truncate_si_psi' insns are needed since we can't -;; do logic on PSImode. Adding PSImode logic patterns works, but loading -;; a PSImode constant causes a double indirection, since the SH constant pool -;; is not aware of it. -;; FIXME: We could treat the FPSCR reg as SImode, but currently this causes -;; additional troubles. -(define_insn "extend_psi_si" - [(set (match_operand:SI 0 "arith_reg_dest" "=r") - (zero_extend:SI (match_operand:PSI 1 "arith_reg_operand" "0")))] - "TARGET_SH1" - "" - [(set_attr "length" "0")]) + rtx b = gen_reg_rtx (SImode); + emit_insn (gen_sts_fpscr (b)); -(define_insn "truncate_si_psi" - [(set (match_operand:PSI 0 "arith_reg_dest" "=r") - (truncate:PSI (match_operand:SI 1 "arith_reg_operand" "0")))] - "TARGET_SH1" - "" - [(set_attr "length" "0")]) + rtx a_xor_b = gen_reg_rtx (SImode); + emit_insn (gen_xorsi3 (a_xor_b, a, b)); + + rtx a_xor_b_and_mask = gen_reg_rtx (SImode); + emit_insn (gen_andsi3 (a_xor_b_and_mask, a_xor_b, mask)); + + rtx r = gen_reg_rtx (SImode); + emit_insn (gen_xorsi3 (r, a_xor_b_and_mask, a)); + emit_insn (gen_lds_fpscr (r)); + DONE; +}) ;; ??? This uses the fp unit, but has no type indicating that. ;; If we did that, this would either give a bogus latency or introduce @@ -12306,8 +12281,8 @@ label: ;; it is probably best to claim no function unit, which matches the ;; current setting. (define_insn "toggle_sz" - [(set (reg:PSI FPSCR_REG) - (xor:PSI (reg:PSI FPSCR_REG) (const_int FPSCR_SZ))) + [(set (reg:SI FPSCR_REG) + (xor:SI (reg:SI FPSCR_REG) (const_int FPSCR_SZ))) (set (reg:SI FPSCR_MODES_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" @@ -12317,8 +12292,8 @@ label: ;; Toggle FPU precision PR mode. (define_insn "toggle_pr" - [(set (reg:PSI FPSCR_REG) - (xor:PSI (reg:PSI FPSCR_REG) (const_int FPSCR_PR))) + [(set (reg:SI FPSCR_REG) + (xor:SI (reg:SI FPSCR_REG) (const_int FPSCR_PR))) (set (reg:SI FPSCR_MODES_REG) (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))] "TARGET_SH4A_FP" |