Hi, As discussed in the PR, the __fpscr_values based FPU mode switching is replaced by other means, which preserve the other FPU mode and status bits across mode switches. For details please refer to the coments in the PR.
Tested on sh-sim with -m4 -ml and -m4 -mb without new failures, except for the expected interrupt function handling breakage. As discussed in the PR those not so common cases will be fixed later. Committed as r216307. Cheers, Oleg gcc/ChangeLog PR target/53513 * config/sh/sh-protos.h (emit_sf_insn, emit_df_insn, expand_sf_unop, expand_sf_binop, expand_df_unop, expand_df_binop): Remove. * config/sh/sh.c (sh_emit_set_t_insn): Adjust generated insn pattern to match fp insn patterns. (calc_live_regs): Add FPSCR_MODES_REG and FPSCR_STAT_REG to the ignore list. (emit_sf_insn, emit_df_insn, expand_sf_unop, expand_sf_binop, expand_df_unop, expand_df_binop): Remove. (sh_conditional_register_usage): Mark FPSCR_MODES_REG and FPSCR_STAT_REG as not call clobbered. (sh_emit_mode_set): Emit fpscr store-modify-load sequence instead of invoking fpscr_set_from_mem. * config/sh/sh.h (MAX_REGISTER_NAME_LENGTH): Increase to 6. (SH_REGISTER_NAMES_INITIALIZER): Add names for FPSCR_MODES_REG and FPSCR_STAT_REG. (REGISTER_NAMES): Adjust. (SPECIAL_REGISTER_P): Add FPSCR_MODES_REG and FPSCR_STAT_REG. (FIRST_PSEUDO_REGISTER): Increase to 156. (DWARF_FRAME_REGISTERS): Define as 153 to keep the original value. (FIXED_REGISTERS, CALL_USED_REGISTERS): Add FPSCR_MODES_REG and FPSCR_STAT_REG. (REG_CLASS_CONTENTS): Adjust ALL_REGS bit mask to include FPSCR_MODES_REG and FPSCR_STAT_REG. (REG_ALLOC_ORDER): Add FPSCR_MODES_REG and FPSCR_STAT_REG. * config/sh/sh.md (FPSCR_MODES_REG, FPSCR_STAT_REG, FPSCR_PR, FPSCR_SZ): Add new constants. (UNSPECV_FPSCR_MODES, UNSPECV_FPSCR_STAT): Add new unspecv constants. (movpsi): Use TARGET_FPU_ANY condition, invoke gen_fpu_switch. (fpu_switch): Add use and set of FPSCR_STAT_REG and FPSCR_MODES_REG. Use TARGET_FPU_ANY condition. (fpu_switch peephole2): Remove. (fpu_switch split): Use simple_mem_operand to capture the mem and adjust split implementation. (extend_psi_si, truncate_si_psi): New insns. (toggle_sz, toggle_pr): Use FPSCR_SZ, FPSCR_PR constants. Add set of FPSCR_MODES_REG. (push_e, push_4, pop_e, pop_4, movdf_i4, reload_indf__frn, movsf_ie, reload_insf__frn, force_mode_for_call, calli, calli_tbr_rel, calli_pcrel, call_pcrel, call_compact, call_compact_rettramp, call_valuei, call_valuei_tbr_rel, call_valuei_pcrel, call_value_pcrel, call_value_compact, call_value_compact_rettramp, call, call_pop_compact, call_pop_compact_rettramp, call_value, sibcalli, sibcalli_pcrel, sibcalli_thunk, sibcall_pcrel, sibcall_compact, sibcall, sibcall_valuei, sibcall_valuei_pcrel, sibcall_value_pcrel, sibcall_value_compact, sibcall_value, call_value_pop_compact, call_value_pop_compact_rettramp, various unnamed splits): Replace use of FPSCR_REG with use of FPSCR_MODES_REG. Adjust gen_* function uses. (floatsisf2_i4, *floatsisf2_ie): Merge into floatsisf2_i4. (fix_truncsfsi2_i4, *fixsfsi): Merge into fix_truncsfsi2_i4. (cmpgtsf_t, cmpgtsf_t_i4): Merge into cmpgtsf_t. (cmpeqsf_t, cmpeqsf_t_i4): Merge into cmpeqsf_t. (ieee_ccmpeqsf_t, *ieee_ccmpeqsf_t_4): Merge into ieee_ccmpeqsf_t. (udivsi3_i4, divsi3_i4, addsf3_i, subsf3_i, mulsf3_i, fmasf4_i, *fmasf4, divsf3_i, floatsisf2_i4, fix_truncsfsi2_i4, cmpgtsf_t, cmpeqsf_t, ieee_ccmpeqsf_t, sqrtsf2_i, rsqrtsf2, fsca, adddf3_i, subdf3_i, muldf3_i, divdf3_i, floatsidf2_i, fix_truncdfsi2_i, cmpgtdf_t, cmpeqdf_t, *ieee_ccmpeqdf_t, sqrtdf2_i, extendsfdf2_i4, truncdfsf2_i4): Replace use of FPSCR_REG with clobber of FPSCR_STAT_REG and use of FPSCR_MODES_REG. Adjust gen_* function uses. gcc/testsuite/ChangeLog PR target/53513 * gcc.target/sh/pr54680.c: Adjust matching of lds insn.
Index: gcc/config/sh/sh.c =================================================================== --- gcc/config/sh/sh.c (revision 216300) +++ gcc/config/sh/sh.c (working copy) @@ -2281,20 +2281,20 @@ return t ^ (cmpval == cmpop); } -/* Emit INSN, possibly in a PARALLEL with an USE of fpscr for SH4. */ - +/* Emit INSN, possibly in a PARALLEL with an USE/CLOBBER of FPSCR bits in case + of floating-point comparisons. */ static void sh_emit_set_t_insn (rtx insn, enum machine_mode mode) { - if ((TARGET_SH4 || TARGET_SH2A) && GET_MODE_CLASS (mode) == MODE_FLOAT) + if (TARGET_FPU_ANY && GET_MODE_CLASS (mode) == MODE_FLOAT + && GET_CODE (insn) != PARALLEL) { insn = gen_rtx_PARALLEL (VOIDmode, - gen_rtvec (2, insn, - gen_rtx_USE (VOIDmode, get_fpscr_rtx ()))); - (mode == SFmode ? emit_sf_insn : emit_df_insn) (insn); + gen_rtvec (3, insn, + gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, FPSCR_STAT_REG)), + gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, FPSCR_MODES_REG)))); } - else - emit_insn (insn); + emit_insn (insn); } /* Prepare the operands for an scc instruction; make sure that the @@ -7250,6 +7250,7 @@ && reg != STACK_POINTER_REGNUM && reg != ARG_POINTER_REGNUM && reg != RETURN_ADDRESS_POINTER_REGNUM && reg != T_REG && reg != GBR_REG + && reg != FPSCR_MODES_REG && reg != FPSCR_STAT_REG /* Push fpscr only on targets which have FPU */ && (reg != FPSCR_REG || TARGET_FPU_ANY)) : (/* Only push those regs which are used and need to be saved. */ @@ -10070,44 +10071,6 @@ dst = get_fpscr_rtx (); emit_move_insn (dst, src); } - -void -emit_sf_insn (rtx pat) -{ - emit_insn (pat); -} - -void -emit_df_insn (rtx pat) -{ - emit_insn (pat); -} - -void -expand_sf_unop (rtx (*fun) (rtx, rtx, rtx), rtx *operands) -{ - emit_sf_insn ((*fun) (operands[0], operands[1], get_fpscr_rtx ())); -} - -void -expand_sf_binop (rtx (*fun) (rtx, rtx, rtx, rtx), rtx *operands) -{ - emit_sf_insn ((*fun) (operands[0], operands[1], operands[2], - get_fpscr_rtx ())); -} - -void -expand_df_unop (rtx (*fun) (rtx, rtx, rtx), rtx *operands) -{ - emit_df_insn ((*fun) (operands[0], operands[1], get_fpscr_rtx ())); -} - -void -expand_df_binop (rtx (*fun) (rtx, rtx, rtx, rtx), rtx *operands) -{ - emit_df_insn ((*fun) (operands[0], operands[1], operands[2], - get_fpscr_rtx ())); -} static rtx get_free_reg (HARD_REG_SET); @@ -13308,6 +13271,9 @@ for (regno = FIRST_GENERAL_REG; regno <= LAST_GENERAL_REG; regno++) if (! fixed_regs[regno] && call_really_used_regs[regno]) SET_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], regno); + + call_really_used_regs[FPSCR_MODES_REG] = 0; + call_really_used_regs[FPSCR_STAT_REG] = 0; } /* Implement TARGET_LEGITIMATE_CONSTANT_P @@ -13659,7 +13625,7 @@ static void sh_emit_mode_set (int entity ATTRIBUTE_UNUSED, int mode, - int prev_mode, HARD_REG_SET regs_live) + int prev_mode, HARD_REG_SET regs_live ATTRIBUTE_UNUSED) { if ((TARGET_SH4A_FP || TARGET_SH4_300) && prev_mode != FP_MODE_NONE && prev_mode != mode) @@ -13668,8 +13634,36 @@ if (TARGET_FMOVD) emit_insn (gen_toggle_sz ()); } - else - fpscr_set_from_mem (mode, regs_live); + 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 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))); + else if (mode == FP_MODE_SINGLE) + i = gen_andsi3 (tmp1, tmp1, + force_reg (SImode, GEN_INT (~fpbits))); + else if (mode == FP_MODE_DOUBLE) + i = gen_iorsi3 (tmp1, tmp1, + 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); + } } static int Index: gcc/config/sh/sh.h =================================================================== --- gcc/config/sh/sh.h (revision 216300) +++ gcc/config/sh/sh.h (working copy) @@ -574,7 +574,7 @@ fr4..fr11 fp args in fr12..fr15 call saved floating point registers */ -#define MAX_REGISTER_NAME_LENGTH 5 +#define MAX_REGISTER_NAME_LENGTH 6 extern char sh_register_names[][MAX_REGISTER_NAME_LENGTH + 1]; #define SH_REGISTER_NAMES_INITIALIZER \ @@ -598,7 +598,7 @@ "tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7", \ "xd0", "xd2", "xd4", "xd6", "xd8", "xd10", "xd12", "xd14", \ "gbr", "ap", "pr", "t", "mach", "macl", "fpul", "fpscr", \ - "rap", "sfp" \ + "rap", "sfp", "fpscr0", "fpscr1" \ } #define REGNAMES_ARR_INDEX_1(index) \ @@ -623,7 +623,7 @@ REGNAMES_ARR_INDEX_8 (128), \ REGNAMES_ARR_INDEX_8 (136), \ REGNAMES_ARR_INDEX_8 (144), \ - REGNAMES_ARR_INDEX_2 (152) \ + REGNAMES_ARR_INDEX_4 (152) \ } #define ADDREGNAMES_SIZE 32 @@ -711,7 +711,8 @@ #define SPECIAL_REGISTER_P(REGNO) \ ((REGNO) == GBR_REG || (REGNO) == T_REG \ - || (REGNO) == MACH_REG || (REGNO) == MACL_REG) + || (REGNO) == MACH_REG || (REGNO) == MACL_REG \ + || (REGNO) == FPSCR_MODES_REG || (REGNO) == FPSCR_STAT_REG) #define TARGET_REGISTER_P(REGNO) \ ((int) (REGNO) >= FIRST_TARGET_REG && (int) (REGNO) <= LAST_TARGET_REG) @@ -738,10 +739,10 @@ ? DImode \ : SImode) -#define FIRST_PSEUDO_REGISTER 154 +#define FIRST_PSEUDO_REGISTER 156 /* Don't count soft frame pointer. */ -#define DWARF_FRAME_REGISTERS (FIRST_PSEUDO_REGISTER - 1) +#define DWARF_FRAME_REGISTERS (153) /* 1 for registers that have pervasive standard uses and are not available for the register allocator. @@ -777,8 +778,8 @@ 0, 0, 0, 0, 0, 0, 0, 0, \ /*"gbr", "ap", "pr", "t", "mach", "macl", "fpul", "fpscr", */ \ 1, 1, 1, 1, 1, 1, 0, 1, \ -/*"rap", "sfp" */ \ - 1, 1, \ +/*"rap", "sfp","fpscr0","fpscr1" */ \ + 1, 1, 1, 1, \ } /* 1 for registers not available across function calls. @@ -816,8 +817,8 @@ 1, 1, 1, 1, 1, 1, 0, 0, \ /*"gbr", "ap", "pr", "t", "mach", "macl", "fpul", "fpscr", */ \ 1, 1, 1, 1, 1, 1, 1, 1, \ -/*"rap", "sfp" */ \ - 1, 1, \ +/*"rap", "sfp","fpscr0","fpscr1" */ \ + 1, 1, 1, 1, \ } /* TARGET_CONDITIONAL_REGISTER_USAGE might want to make a register @@ -1072,7 +1073,7 @@ /* TARGET_REGS: */ \ { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x000000ff }, \ /* ALL_REGS: */ \ - { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x03ffffff }, \ + { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0fffffff }, \ } /* The same information, inverted: @@ -1122,7 +1123,7 @@ 128,129,130,131,132,133,134,135, \ /* Fixed registers */ \ 15, 16, 24, 25, 26, 27, 63,144, \ - 145,146,147,148,149,152,153 } + 145,146,147,148,149,152,153,154,155 } /* The class value for index registers, and the one for base regs. */ #define INDEX_REG_CLASS \ Index: gcc/config/sh/sh.md =================================================================== --- gcc/config/sh/sh.md (revision 216300) +++ gcc/config/sh/sh.md (working copy) @@ -76,6 +76,12 @@ (FPSCR_REG 151) + ;; Virtual FPSCR - bits that are used by FP ops. + (FPSCR_MODES_REG 154) + + ;; Virtual FPSCR - bits that are updated by FP ops. + (FPSCR_STAT_REG 155) + (PIC_REG 12) (FP_REG 14) (SP_REG 15) @@ -109,6 +115,9 @@ (TR2_REG 130) (XD0_REG 136) + + (FPSCR_PR 524288) + (FPSCR_SZ 1048576) ]) (define_c_enum "unspec" [ @@ -176,6 +185,9 @@ UNSPECV_GBR UNSPECV_SP_SWITCH_B UNSPECV_SP_SWITCH_E + + UNSPECV_FPSCR_MODES + UNSPECV_FPSCR_STAT ]) ;; ------------------------------------------------------------------------- @@ -2395,7 +2407,8 @@ (clobber (reg:SI R1_REG)) (clobber (reg:SI R4_REG)) (clobber (reg:SI R5_REG)) - (use (reg:PSI FPSCR_REG)) + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG)) (use (match_operand:SI 1 "arith_reg_operand" "r"))] "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE" "jsr @%1%#" @@ -2666,7 +2679,8 @@ (clobber (reg:SI PR_REG)) (clobber (reg:DF DR0_REG)) (clobber (reg:DF DR2_REG)) - (use (reg:PSI FPSCR_REG)) + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG)) (use (match_operand:SI 1 "arith_reg_operand" "r"))] "TARGET_FPU_DOUBLE && ! TARGET_FPU_SINGLE" "jsr @%1%#" @@ -6444,7 +6458,7 @@ (define_expand "push_e" [(parallel [(set (mem:SF (pre_dec:SI (reg:SI SP_REG))) (match_operand:SF 0 "" "")) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (scratch:SI))])] "TARGET_SH1 && ! TARGET_SH5" "") @@ -6462,7 +6476,7 @@ (define_expand "push_4" [(parallel [(set (mem:DF (pre_dec:SI (reg:SI SP_REG))) (match_operand:DF 0 "" "")) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (scratch:SI))])] "TARGET_SH1 && ! TARGET_SH5" "") @@ -6470,7 +6484,7 @@ (define_expand "pop_e" [(parallel [(set (match_operand:SF 0 "" "") (mem:SF (post_inc:SI (reg:SI SP_REG)))) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (scratch:SI))])] "TARGET_SH1 && ! TARGET_SH5" "") @@ -6485,7 +6499,7 @@ (define_expand "pop_4" [(parallel [(set (match_operand:DF 0 "" "") (mem:DF (post_inc:SI (reg:SI SP_REG)))) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (scratch:SI))])] "TARGET_SH1 && ! TARGET_SH5" "") @@ -7655,8 +7669,8 @@ (define_insn "movdf_i4" [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d") (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r")) - (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c")) - (clobber (match_scratch:SI 3 "=X,X,&z,X,X,X,X,X,X,X"))] + (use (reg:SI FPSCR_MODES_REG)) + (clobber (match_scratch:SI 2 "=X,X,&z,X,X,X,X,X,X,X"))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && (arith_reg_operand (operands[0], DFmode) || arith_reg_operand (operands[1], DFmode))" @@ -7711,8 +7725,8 @@ (define_split [(set (match_operand:DF 0 "register_operand") (match_operand:DF 1 "register_operand")) - (use (match_operand:PSI 2 "fpscr_operand")) - (clobber (match_scratch:SI 3))] + (use (reg:SI FPSCR_MODES_REG)) + (clobber (match_scratch:SI 2))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed && (true_regnum (operands[0]) < 16) != (true_regnum (operands[1]) < 16)" [(const_int 0)] @@ -7728,7 +7742,7 @@ else tos = gen_tmp_stack_mem (DFmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx)); - insn = emit_insn (gen_movdf_i4 (tos, operands[1], operands[2])); + insn = emit_insn (gen_movdf_i4 (tos, operands[1])); if (! (TARGET_SH5 && true_regnum (operands[1]) < 16)) add_reg_note (insn, REG_INC, stack_pointer_rtx); if (TARGET_SH5 && true_regnum (operands[0]) < 16) @@ -7736,7 +7750,7 @@ else tos = gen_tmp_stack_mem (DFmode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx)); - insn = emit_insn (gen_movdf_i4 (operands[0], tos, operands[2])); + insn = emit_insn (gen_movdf_i4 (operands[0], tos)); if (TARGET_SH5 && true_regnum (operands[0]) < 16) emit_move_insn (stack_pointer_rtx, plus_constant (Pmode, stack_pointer_rtx, 8)); @@ -7752,8 +7766,8 @@ (define_split [(set (match_operand:DF 0 "general_movdst_operand" "") (match_operand:DF 1 "general_movsrc_operand" "")) - (use (match_operand:PSI 2 "fpscr_operand" "")) - (clobber (match_scratch:SI 3 ""))] + (use (reg:SI FPSCR_MODES_REG)) + (clobber (match_scratch:SI 2))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed && true_regnum (operands[0]) < 16 @@ -7824,18 +7838,18 @@ (define_split [(set (match_operand:DF 0 "register_operand" "") (match_operand:DF 1 "memory_operand" "")) - (use (match_operand:PSI 2 "fpscr_operand" "")) + (use (reg:SI FPSCR_MODES_REG)) (clobber (reg:SI R0_REG))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && reload_completed" [(parallel [(set (match_dup 0) (match_dup 1)) - (use (match_dup 2)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (scratch:SI))])] "") (define_expand "reload_indf__frn" [(parallel [(set (match_operand:DF 0 "register_operand" "=a") (match_operand:DF 1 "immediate_operand" "FQ")) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (match_operand:SI 2 "register_operand" "=&z"))])] "TARGET_SH1" "") @@ -7851,8 +7865,8 @@ (define_split [(set (match_operand:SF 0 "register_operand" "") (match_operand:SF 1 "register_operand" "")) - (use (match_operand:PSI 2 "fpscr_operand" "")) - (clobber (match_scratch:SI 3 ""))] + (use (reg:SI FPSCR_MODES_REG)) + (clobber (match_scratch:SI 2))] "TARGET_SH2E && reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])" [(set (match_dup 0) (match_dup 0))] @@ -7862,8 +7876,8 @@ (define_split [(set (match_operand:DF 0 "register_operand" "") (match_operand:DF 1 "register_operand" "")) - (use (match_operand:PSI 2 "fpscr_operand" "")) - (clobber (match_scratch:SI 3 ""))] + (use (reg:SI FPSCR_MODES_REG)) + (clobber (match_scratch:SI 2))] "TARGET_SH4 && ! TARGET_FMOVD && reload_completed && FP_OR_XD_REGISTER_P (true_regnum (operands[0])) && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))" @@ -7871,17 +7885,17 @@ { int dst = true_regnum (operands[0]), src = true_regnum (operands[1]); emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst), - gen_rtx_REG (SFmode, src), operands[2])); + gen_rtx_REG (SFmode, src))); emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, dst + 1), - gen_rtx_REG (SFmode, src + 1), operands[2])); + gen_rtx_REG (SFmode, src + 1))); DONE; }) (define_split [(set (match_operand:DF 0 "register_operand" "") (mem:DF (match_operand:SI 1 "register_operand" ""))) - (use (match_operand:PSI 2 "fpscr_operand" "")) - (clobber (match_scratch:SI 3 ""))] + (use (reg:SI FPSCR_MODES_REG)) + (clobber (match_scratch:SI 2))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed && FP_OR_XD_REGISTER_P (true_regnum (operands[0])) && find_regno_note (insn, REG_DEAD, true_regnum (operands[1]))" @@ -7894,20 +7908,19 @@ = change_address (mem, SFmode, gen_rtx_POST_INC (Pmode, operands[1])); insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, regno + SH_REG_MSW_OFFSET), - mem2, operands[2])); + mem2)); add_reg_note (insn, REG_INC, operands[1]); insn = emit_insn (gen_movsf_ie (gen_rtx_REG (SFmode, regno + SH_REG_LSW_OFFSET), - change_address (mem, SFmode, NULL_RTX), - operands[2])); + change_address (mem, SFmode, NULL_RTX))); DONE; }) (define_split [(set (match_operand:DF 0 "register_operand" "") (match_operand:DF 1 "memory_operand" "")) - (use (match_operand:PSI 2 "fpscr_operand" "")) - (clobber (match_scratch:SI 3 ""))] + (use (reg:SI FPSCR_MODES_REG)) + (clobber (match_scratch:SI 2))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed && FP_OR_XD_REGISTER_P (true_regnum (operands[0]))" [(const_int 0)] @@ -7930,10 +7943,10 @@ if (! arith_reg_operand (operands[1], SFmode)) { XEXP (mem2, 0) = addr = gen_rtx_POST_INC (SImode, addr); - insn = emit_insn (gen_movsf_ie (reg0, mem2, operands[2])); + insn = emit_insn (gen_movsf_ie (reg0, mem2)); add_reg_note (insn, REG_INC, XEXP (addr, 0)); - emit_insn (gen_movsf_ie (reg1, operands[1], operands[2])); + emit_insn (gen_movsf_ie (reg1, operands[1])); /* If we have modified the stack pointer, the value that we have read with post-increment might be modified by an interrupt, @@ -7948,17 +7961,17 @@ /* Fall through. */ case PLUS: - emit_insn (gen_movsf_ie (reg0, operands[1], operands[2])); + emit_insn (gen_movsf_ie (reg0, operands[1])); operands[1] = copy_rtx (operands[1]); XEXP (operands[1], 0) = plus_constant (Pmode, addr, 4); - emit_insn (gen_movsf_ie (reg1, operands[1], operands[2])); + emit_insn (gen_movsf_ie (reg1, operands[1])); break; case POST_INC: - insn = emit_insn (gen_movsf_ie (reg0, operands[1], operands[2])); + insn = emit_insn (gen_movsf_ie (reg0, operands[1])); add_reg_note (insn, REG_INC, XEXP (addr, 0)); - insn = emit_insn (gen_movsf_ie (reg1, operands[1], operands[2])); + insn = emit_insn (gen_movsf_ie (reg1, operands[1])); add_reg_note (insn, REG_INC, XEXP (addr, 0)); break; @@ -7973,8 +7986,8 @@ (define_split [(set (match_operand:DF 0 "memory_operand" "") (match_operand:DF 1 "register_operand" "")) - (use (match_operand:PSI 2 "fpscr_operand" "")) - (clobber (match_scratch:SI 3 ""))] + (use (reg:SI FPSCR_MODES_REG)) + (clobber (match_scratch:SI 2))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && ! TARGET_FMOVD && reload_completed && FP_OR_XD_REGISTER_P (true_regnum (operands[1]))" [(const_int 0)] @@ -7997,12 +8010,12 @@ if (! arith_reg_operand (operands[0], SFmode)) { emit_insn (gen_addsi3 (addr, addr, GEN_INT (4))); - emit_insn (gen_movsf_ie (operands[0], reg1, operands[2])); + emit_insn (gen_movsf_ie (operands[0], reg1)); operands[0] = copy_rtx (operands[0]); XEXP (operands[0], 0) = addr = gen_rtx_PRE_DEC (SImode, addr); - insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2])); + insn = emit_insn (gen_movsf_ie (operands[0], reg0)); add_reg_note (insn, REG_INC, XEXP (addr, 0)); break; } @@ -8014,12 +8027,12 @@ register component of the address. Just emit the lower numbered register first, to the lower address, then the higher numbered register to the higher address. */ - emit_insn (gen_movsf_ie (operands[0], reg0, operands[2])); + emit_insn (gen_movsf_ie (operands[0], reg0)); operands[0] = copy_rtx (operands[0]); XEXP (operands[0], 0) = plus_constant (Pmode, addr, 4); - emit_insn (gen_movsf_ie (operands[0], reg1, operands[2])); + emit_insn (gen_movsf_ie (operands[0], reg1)); break; case PRE_DEC: @@ -8027,10 +8040,10 @@ first (ie the word in the higher numbered register) then the word to go to the lower address. */ - insn = emit_insn (gen_movsf_ie (operands[0], reg1, operands[2])); + insn = emit_insn (gen_movsf_ie (operands[0], reg1)); add_reg_note (insn, REG_INC, XEXP (addr, 0)); - insn = emit_insn (gen_movsf_ie (operands[0], reg0, operands[2])); + insn = emit_insn (gen_movsf_ie (operands[0], reg0)); add_reg_note (insn, REG_INC, XEXP (addr, 0)); break; @@ -8112,7 +8125,7 @@ } if (TARGET_SH4 || TARGET_SH2A_DOUBLE) { - emit_df_insn (gen_movdf_i4 (operands[0], operands[1], get_fpscr_rtx ())); + emit_insn (gen_movdf_i4 (operands[0], operands[1])); DONE; } }) @@ -8357,12 +8370,12 @@ "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y") (match_operand:SF 1 "general_movsrc_operand" "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y")) - (use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c")) - (clobber (match_scratch:SI 3 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))] + (use (reg:SI FPSCR_MODES_REG)) + (clobber (match_scratch:SI 2 "=X,X,Bsc,Bsc,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))] "TARGET_SH2E && (arith_reg_operand (operands[0], SFmode) || fpul_operand (operands[0], SFmode) || arith_reg_operand (operands[1], SFmode) || fpul_operand (operands[1], SFmode) - || arith_reg_operand (operands[3], SImode))" + || arith_reg_operand (operands[2], SImode))" "@ fmov %1,%0 mov %1,%0 @@ -8441,14 +8454,14 @@ (define_split [(set (match_operand:SF 0 "register_operand" "") (match_operand:SF 1 "register_operand" "")) - (use (match_operand:PSI 2 "fpscr_operand" "")) + (use (reg:SI FPSCR_MODES_REG)) (clobber (reg:SI FPUL_REG))] "TARGET_SH1" [(parallel [(set (reg:SF FPUL_REG) (match_dup 1)) - (use (match_dup 2)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (scratch:SI))]) (parallel [(set (match_dup 0) (reg:SF FPUL_REG)) - (use (match_dup 2)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (scratch:SI))])] "") @@ -8468,7 +8481,7 @@ } if (TARGET_SH2E) { - emit_sf_insn (gen_movsf_ie (operands[0], operands[1], get_fpscr_rtx ())); + emit_insn (gen_movsf_ie (operands[0], operands[1])); DONE; } }) @@ -8483,7 +8496,7 @@ (define_expand "reload_insf__frn" [(parallel [(set (match_operand:SF 0 "register_operand" "=a") (match_operand:SF 1 "immediate_operand" "FQ")) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (match_operand:SI 2 "register_operand" "=&z"))])] "TARGET_SH1" "") @@ -8929,7 +8942,7 @@ }) (define_insn "force_mode_for_call" - [(use (reg:PSI FPSCR_REG))] + [(use (reg:SI FPSCR_MODES_REG))] "TARGET_SHCOMPACT" "" [(set_attr "length" "0") @@ -8940,7 +8953,7 @@ (define_insn "calli" [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r")) (match_operand 1 "" "")) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (reg:SI PR_REG))] "TARGET_SH1" { @@ -8962,7 +8975,7 @@ (define_insn "calli_tbr_rel" [(call (mem (match_operand:SI 0 "symbol_ref_operand" "")) (match_operand 1 "" "")) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (reg:SI PR_REG))] "TARGET_SH2A && sh2a_is_function_vector_call (operands[0])" { @@ -8983,7 +8996,7 @@ (define_insn "calli_pcrel" [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r")) (match_operand 1 "" "")) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (use (reg:SI PIC_REG)) (use (match_operand 2 "" "")) (clobber (reg:SI PR_REG))] @@ -9002,7 +9015,7 @@ (define_insn_and_split "call_pcrel" [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "")) (match_operand 1 "" "")) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (use (reg:SI PIC_REG)) (clobber (reg:SI PR_REG)) (clobber (match_scratch:SI 2 "=r"))] @@ -9033,7 +9046,7 @@ (match_operand 2 "immediate_operand" "n") (use (reg:SI R0_REG)) (use (reg:SI R1_REG)) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (reg:SI PR_REG))] "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))" "jsr @%0%#" @@ -9049,7 +9062,7 @@ (match_operand 2 "immediate_operand" "n") (use (reg:SI R0_REG)) (use (reg:SI R1_REG)) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (reg:SI R10_REG)) (clobber (reg:SI PR_REG))] "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))" @@ -9072,7 +9085,7 @@ [(set (match_operand 0 "" "=rf") (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r")) (match_operand 2 "" ""))) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (reg:SI PR_REG))] "TARGET_SH1" { @@ -9095,7 +9108,7 @@ [(set (match_operand 0 "" "=rf") (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "")) (match_operand 2 "" ""))) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (reg:SI PR_REG))] "TARGET_SH2A && sh2a_is_function_vector_call (operands[1])" { @@ -9116,7 +9129,7 @@ [(set (match_operand 0 "" "=rf") (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "r")) (match_operand 2 "" ""))) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (use (reg:SI PIC_REG)) (use (match_operand 3 "" "")) (clobber (reg:SI PR_REG))] @@ -9136,7 +9149,7 @@ [(set (match_operand 0 "" "=rf") (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "")) (match_operand 2 "" ""))) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (use (reg:SI PIC_REG)) (clobber (reg:SI PR_REG)) (clobber (match_scratch:SI 3 "=r"))] @@ -9169,7 +9182,7 @@ (match_operand 3 "immediate_operand" "n") (use (reg:SI R0_REG)) (use (reg:SI R1_REG)) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (reg:SI PR_REG))] "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))" "jsr @%1%#" @@ -9186,7 +9199,7 @@ (match_operand 3 "immediate_operand" "n") (use (reg:SI R0_REG)) (use (reg:SI R1_REG)) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (reg:SI R10_REG)) (clobber (reg:SI PR_REG))] "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))" @@ -9210,7 +9223,7 @@ [(parallel [(call (mem:SI (match_operand 0 "arith_reg_operand" "")) (match_operand 1 "" "")) (match_operand 2 "" "") - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (reg:SI PR_REG))])] "" { @@ -9309,7 +9322,7 @@ (match_operand 3 "immediate_operand" "n"))) (use (reg:SI R0_REG)) (use (reg:SI R1_REG)) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (reg:SI PR_REG))] "TARGET_SHCOMPACT && ! (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))" "jsr @%0%#" @@ -9327,7 +9340,7 @@ (match_operand 3 "immediate_operand" "n"))) (use (reg:SI R0_REG)) (use (reg:SI R1_REG)) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (reg:SI R10_REG)) (clobber (reg:SI PR_REG))] "TARGET_SHCOMPACT && (INTVAL (operands[2]) & CALL_COOKIE_RET_TRAMP (1))" @@ -9398,7 +9411,7 @@ (call (mem:SI (match_operand 1 "arith_reg_operand" "")) (match_operand 2 "" ""))) (match_operand 3 "" "") - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (reg:SI PR_REG))])] "" { @@ -9493,7 +9506,7 @@ (define_insn "sibcalli" [(call (mem:SI (match_operand:SI 0 "register_operand" "k")) (match_operand 1 "" "")) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (return)] "TARGET_SH1" "jmp @%0%#" @@ -9507,7 +9520,7 @@ [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "k")) (match_operand 1 "" "")) (use (match_operand 2 "" "")) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (return)] "TARGET_SH2" { @@ -9525,7 +9538,7 @@ [(call (mem:SI (unspec:SI [(match_operand:SI 0 "symbol_ref_operand" "")] UNSPEC_THUNK)) (match_operand 1 "" "")) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (return)] "TARGET_SH1" "bra %O0" @@ -9539,7 +9552,7 @@ (define_insn_and_split "sibcall_pcrel" [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "")) (match_operand 1 "" "")) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (match_scratch:SI 2 "=k")) (return)] "TARGET_SH2" @@ -9568,7 +9581,7 @@ (return) (use (match_operand:SI 2 "register_operand" "z,x")) (use (reg:SI R1_REG)) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) ;; We want to make sure the `x' above will only match MACH_REG ;; because sibcall_epilogue may clobber MACL_REG. (clobber (reg:SI MACL_REG))] @@ -9602,7 +9615,7 @@ [(call (mem:SI (match_operand 0 "arith_reg_operand" "")) (match_operand 1 "" "")) (match_operand 2 "" "") - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (return)])] "" { @@ -9699,7 +9712,7 @@ [(set (match_operand 0 "" "=rf") (call (mem:SI (match_operand:SI 1 "register_operand" "k")) (match_operand 2 "" ""))) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (return)] "TARGET_SH1" "jmp @%1%#" @@ -9714,7 +9727,7 @@ (call (mem:SI (match_operand:SI 1 "arith_reg_operand" "k")) (match_operand 2 "" ""))) (use (match_operand 3 "" "")) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (return)] "TARGET_SH2" { @@ -9731,7 +9744,7 @@ [(set (match_operand 0 "" "=rf") (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "")) (match_operand 2 "" ""))) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (match_scratch:SI 3 "=k")) (return)] "TARGET_SH2" @@ -9763,7 +9776,7 @@ (return) (use (match_operand:SI 3 "register_operand" "z,x")) (use (reg:SI R1_REG)) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) ;; We want to make sure the `x' above will only match MACH_REG ;; because sibcall_epilogue may clobber MACL_REG. (clobber (reg:SI MACL_REG))] @@ -9799,7 +9812,7 @@ (call (mem:SI (match_operand 1 "arith_reg_operand" "")) (match_operand 2 "" ""))) (match_operand 3 "" "") - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (return)])] "" { @@ -9905,7 +9918,7 @@ (match_operand 3 "immediate_operand" "n") (use (reg:SI R0_REG)) (use (reg:SI R1_REG)) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (reg:SI PR_REG))] "TARGET_SHCOMPACT && ! (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))" "jsr @%1%#" @@ -9924,7 +9937,7 @@ (match_operand 3 "immediate_operand" "n") (use (reg:SI R0_REG)) (use (reg:SI R1_REG)) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (clobber (reg:SI R10_REG)) (clobber (reg:SI PR_REG))] "TARGET_SHCOMPACT && (INTVAL (operands[3]) & CALL_COOKIE_RET_TRAMP (1))" @@ -10430,7 +10443,7 @@ (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_TLSGD)) (const_int 0))) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (use (reg:SI PIC_REG)) (clobber (reg:SI PR_REG)) (clobber (scratch:SI))] @@ -10457,7 +10470,7 @@ (call:SI (mem:SI (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_TLSLDM)) (const_int 0))) - (use (reg:PSI FPSCR_REG)) + (use (reg:SI FPSCR_MODES_REG)) (use (reg:SI PIC_REG)) (clobber (reg:SI PR_REG)) (clobber (scratch:SI))] @@ -12199,8 +12212,11 @@ (define_expand "movpsi" [(set (match_operand:PSI 0 "register_operand" "") (match_operand:PSI 1 "general_movsrc_operand" ""))] - "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" - "") + "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. @@ -12211,8 +12227,14 @@ ;; 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"))] - "TARGET_SH2E + (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)) + (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]) @@ -12231,44 +12253,52 @@ (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store, mac_gp,fstore")]) -(define_peephole2 +(define_split [(set (reg:PSI FPSCR_REG) - (mem:PSI (match_operand:SI 0 "register_operand" "")))] - "(TARGET_SH4 || TARGET_SH2A_DOUBLE) && peep2_reg_dead_p (1, operands[0])" + (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)] { - rtx fpscr, mem, new_insn; + rtx addrreg = XEXP (operands[0], 0); + rtx mem = replace_equiv_address (operands[0], + gen_rtx_POST_INC (Pmode, addrreg)); - fpscr = SET_DEST (PATTERN (curr_insn)); - mem = SET_SRC (PATTERN (curr_insn)); - mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0])); + add_reg_note (emit_insn (gen_fpu_switch (get_fpscr_rtx (), mem)), + REG_INC, addrreg); - new_insn = emit_insn (gen_fpu_switch (fpscr, mem)); - add_reg_note (new_insn, REG_INC, operands[0]); - DONE; + /* 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))); }) -(define_split - [(set (reg:PSI FPSCR_REG) - (mem:PSI (match_operand:SI 0 "register_operand" "")))] - "(TARGET_SH4 || TARGET_SH2A_DOUBLE) - && (flag_peephole2 ? epilogue_completed : reload_completed)" - [(const_int 0)] -{ - rtx fpscr, mem, new_insn; +;; 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")]) - fpscr = SET_DEST (PATTERN (curr_insn)); - mem = SET_SRC (PATTERN (curr_insn)); - mem = replace_equiv_address (mem, gen_rtx_POST_INC (Pmode, operands[0])); +(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")]) - new_insn = emit_insn (gen_fpu_switch (fpscr, mem)); - add_reg_note (new_insn, REG_INC, operands[0]); - if (!find_regno_note (curr_insn, REG_DEAD, true_regnum (operands[0]))) - emit_insn (gen_addsi3 (operands[0], operands[0], GEN_INT (-4))); - 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 ;; a bogus FIFO constraint. @@ -12277,7 +12307,9 @@ ;; current setting. (define_insn "toggle_sz" [(set (reg:PSI FPSCR_REG) - (xor:PSI (reg:PSI FPSCR_REG) (const_int 1048576)))] + (xor:PSI (reg:PSI 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)" "fschg" [(set_attr "type" "fpscr_toggle") (set_attr "fp_set" "unknown")]) @@ -12286,7 +12318,9 @@ (define_insn "toggle_pr" [(set (reg:PSI FPSCR_REG) - (xor:PSI (reg:PSI FPSCR_REG) (const_int 524288)))] + (xor:PSI (reg:PSI FPSCR_REG) (const_int FPSCR_PR))) + (set (reg:SI FPSCR_MODES_REG) + (unspec_volatile:SI [(const_int 0)] UNSPECV_FPSCR_MODES))] "TARGET_SH4A_FP" "fpchg" [(set_attr "type" "fpscr_toggle")]) @@ -12299,7 +12333,7 @@ { if (TARGET_SH2E) { - expand_sf_binop (&gen_addsf3_i, operands); + emit_insn (gen_addsf3_i (operands[0], operands[1], operands[2])); DONE; } }) @@ -12398,7 +12432,8 @@ [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") (plus:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0") (match_operand:SF 2 "fp_arith_reg_operand" "f"))) - (use (match_operand:PSI 3 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "TARGET_SH2E" "fadd %2,%0" [(set_attr "type" "fp") @@ -12412,7 +12447,7 @@ { if (TARGET_SH2E) { - expand_sf_binop (&gen_subsf3_i, operands); + emit_insn (gen_subsf3_i (operands[0], operands[1], operands[2])); DONE; } }) @@ -12429,7 +12464,8 @@ [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") (minus:SF (match_operand:SF 1 "fp_arith_reg_operand" "0") (match_operand:SF 2 "fp_arith_reg_operand" "f"))) - (use (match_operand:PSI 3 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "TARGET_SH2E" "fsub %2,%0" [(set_attr "type" "fp") @@ -12443,8 +12479,7 @@ { if (TARGET_SH2E) { - emit_insn (gen_mulsf3_i (operands[0], operands[1], operands[2], - get_fpscr_rtx ())); + emit_insn (gen_mulsf3_i (operands[0], operands[1], operands[2])); DONE; } }) @@ -12461,7 +12496,8 @@ [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%0") (match_operand:SF 2 "fp_arith_reg_operand" "f"))) - (use (match_operand:PSI 3 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "TARGET_SH2E" "fmul %2,%0" [(set_attr "type" "fp") @@ -12477,8 +12513,8 @@ { if (TARGET_SH2E) { - emit_sf_insn (gen_fmasf4_i (operands[0], operands[1], operands[2], - operands[3], get_fpscr_rtx ())); + emit_insn (gen_fmasf4_i (operands[0], operands[1], operands[2], + operands[3])); DONE; } }) @@ -12488,7 +12524,8 @@ (fma:SF (match_operand:SF 1 "fp_arith_reg_operand" "w") (match_operand:SF 2 "fp_arith_reg_operand" "f") (match_operand:SF 3 "fp_arith_reg_operand" "0"))) - (use (match_operand:PSI 4 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "TARGET_SH2E" "fmac %1,%2,%0" [(set_attr "type" "fp") @@ -12511,13 +12548,15 @@ (plus:SF (mult:SF (match_operand:SF 1 "fp_arith_reg_operand" "%w") (match_operand:SF 2 "fp_arith_reg_operand" "f")) (match_operand:SF 3 "arith_reg_operand" "0"))) - (use (match_operand:PSI 4 "fpscr_operand"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "TARGET_SH2E && flag_fp_contract_mode != FP_CONTRACT_OFF" "fmac %1,%2,%0" "&& can_create_pseudo_p ()" [(parallel [(set (match_dup 0) (fma:SF (match_dup 1) (match_dup 2) (match_dup 3))) - (use (match_dup 4))])] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))])] { /* Change 'b * a + a' into 'a * b + a'. This is better for register allocation. */ @@ -12548,7 +12587,7 @@ { if (TARGET_SH2E) { - expand_sf_binop (&gen_divsf3_i, operands); + emit_insn (gen_divsf3_i (operands[0], operands[1], operands[2])); DONE; } }) @@ -12565,7 +12604,8 @@ [(set (match_operand:SF 0 "fp_arith_reg_dest" "=f") (div:SF (match_operand:SF 1 "fp_arith_reg_operand" "0") (match_operand:SF 2 "fp_arith_reg_operand" "f"))) - (use (match_operand:PSI 3 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "TARGET_SH2E" "fdiv %2,%0" [(set_attr "type" "fdiv") @@ -12583,10 +12623,9 @@ (float:SF (match_operand:SI 1 "fpul_operand" "")))] "TARGET_SH2E || TARGET_SHMEDIA_FPU" { - if (TARGET_SH4 || TARGET_SH2A_SINGLE) + if (!TARGET_SHMEDIA_FPU) { - emit_sf_insn (gen_floatsisf2_i4 (operands[0], operands[1], - get_fpscr_rtx ())); + emit_insn (gen_floatsisf2_i4 (operands[0], operands[1])); DONE; } }) @@ -12601,19 +12640,13 @@ (define_insn "floatsisf2_i4" [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") (float:SF (match_operand:SI 1 "fpul_operand" "y"))) - (use (match_operand:PSI 2 "fpscr_operand" "c"))] - "(TARGET_SH4 || TARGET_SH2A_SINGLE)" + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] + "TARGET_SH2E" "float %1,%0" [(set_attr "type" "fp") (set_attr "fp_mode" "single")]) -(define_insn "*floatsisf2_ie" - [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") - (float:SF (match_operand:SI 1 "fpul_operand" "y")))] - "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)" - "float %1,%0" - [(set_attr "type" "fp")]) - (define_insn "fix_truncsfdi2" [(set (match_operand:DI 0 "fp_arith_reg_dest" "=f") (fix:DI (match_operand:SF 1 "fp_arith_reg_operand" "f")))] @@ -12626,10 +12659,9 @@ (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))] "TARGET_SH2E || TARGET_SHMEDIA_FPU" { - if (TARGET_SH4 || TARGET_SH2A_SINGLE) + if (!TARGET_SHMEDIA_FPU) { - emit_sf_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1], - get_fpscr_rtx ())); + emit_insn (gen_fix_truncsfsi2_i4 (operands[0], operands[1])); DONE; } }) @@ -12644,46 +12676,20 @@ (define_insn "fix_truncsfsi2_i4" [(set (match_operand:SI 0 "fpul_operand" "=y") (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f"))) - (use (match_operand:PSI 2 "fpscr_operand" "c"))] - "(TARGET_SH4 || TARGET_SH2A_SINGLE)" + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] + "TARGET_SH2E" "ftrc %1,%0" [(set_attr "type" "ftrc_s") (set_attr "fp_mode" "single")]) -;; ??? This pattern is used nowhere. fix_truncsfsi2 always expands to -;; fix_truncsfsi2_i4. -;; (define_insn "fix_truncsfsi2_i4_2" -;; [(set (match_operand:SI 0 "arith_reg_operand" "=r") -;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f"))) -;; (use (reg:PSI FPSCR_REG)) -;; (clobber (reg:SI FPUL_REG))] -;; "TARGET_SH4" -;; "#" -;; [(set_attr "length" "4") -;; (set_attr "fp_mode" "single")]) - -;;(define_split -;; [(set (match_operand:SI 0 "arith_reg_operand" "=r") -;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f"))) -;; (use (match_operand:PSI 2 "fpscr_operand" "c")) -;; (clobber (reg:SI FPUL_REG))] -;; "TARGET_SH4" -;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1))) -;; (use (match_dup 2))]) -;; (set (match_dup 0) (reg:SI FPUL_REG))]) - -(define_insn "*fixsfsi" - [(set (match_operand:SI 0 "fpul_operand" "=y") - (fix:SI (match_operand:SF 1 "fp_arith_reg_operand" "f")))] - "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)" - "ftrc %1,%0" - [(set_attr "type" "fp")]) - (define_insn "cmpgtsf_t" [(set (reg:SI T_REG) (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f") - (match_operand:SF 1 "fp_arith_reg_operand" "f")))] - "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)" + (match_operand:SF 1 "fp_arith_reg_operand" "f"))) + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] + "TARGET_SH2E || TARGET_SH4 || TARGET_SH2A_SINGLE" "fcmp/gt %1,%0" [(set_attr "type" "fp_cmp") (set_attr "fp_mode" "single")]) @@ -12691,8 +12697,10 @@ (define_insn "cmpeqsf_t" [(set (reg:SI T_REG) (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f") - (match_operand:SF 1 "fp_arith_reg_operand" "f")))] - "TARGET_SH2E && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)" + (match_operand:SF 1 "fp_arith_reg_operand" "f"))) + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] + "TARGET_SH2E || TARGET_SH4 || TARGET_SH2A_SINGLE" "fcmp/eq %1,%0" [(set_attr "type" "fp_cmp") (set_attr "fp_mode" "single")]) @@ -12701,41 +12709,10 @@ [(set (reg:SI T_REG) (ior:SI (reg:SI T_REG) (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f") - (match_operand:SF 1 "fp_arith_reg_operand" "f"))))] - "TARGET_SH2E && TARGET_IEEE && ! (TARGET_SH4 || TARGET_SH2A_SINGLE)" -{ - return output_ieee_ccmpeq (insn, operands); -} - [(set_attr "length" "4")]) - - -(define_insn "cmpgtsf_t_i4" - [(set (reg:SI T_REG) - (gt:SI (match_operand:SF 0 "fp_arith_reg_operand" "f") - (match_operand:SF 1 "fp_arith_reg_operand" "f"))) - (use (match_operand:PSI 2 "fpscr_operand" "c"))] - "(TARGET_SH4 || TARGET_SH2A_SINGLE)" - "fcmp/gt %1,%0" - [(set_attr "type" "fp_cmp") - (set_attr "fp_mode" "single")]) - -(define_insn "cmpeqsf_t_i4" - [(set (reg:SI T_REG) - (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f") - (match_operand:SF 1 "fp_arith_reg_operand" "f"))) - (use (match_operand:PSI 2 "fpscr_operand" "c"))] - "(TARGET_SH4 || TARGET_SH2A_SINGLE)" - "fcmp/eq %1,%0" - [(set_attr "type" "fp_cmp") - (set_attr "fp_mode" "single")]) - -(define_insn "*ieee_ccmpeqsf_t_4" - [(set (reg:SI T_REG) - (ior:SI (reg:SI T_REG) - (eq:SI (match_operand:SF 0 "fp_arith_reg_operand" "f") (match_operand:SF 1 "fp_arith_reg_operand" "f")))) - (use (match_operand:PSI 2 "fpscr_operand" "c"))] - "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_SINGLE)" + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] + "TARGET_IEEE && TARGET_SH2E" { return output_ieee_ccmpeq (insn, operands); } @@ -12817,7 +12794,7 @@ { if (TARGET_SH3E) { - expand_sf_unop (&gen_sqrtsf2_i, operands); + emit_insn (gen_sqrtsf2_i (operands[0], operands[1])); DONE; } }) @@ -12832,7 +12809,8 @@ (define_insn "sqrtsf2_i" [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") (sqrt:SF (match_operand:SF 1 "fp_arith_reg_operand" "0"))) - (use (match_operand:PSI 2 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "TARGET_SH3E" "fsqrt %0" [(set_attr "type" "fdiv") @@ -12842,7 +12820,8 @@ [(set (match_operand:SF 0 "fp_arith_reg_operand" "=f") (div:SF (match_operand:SF 1 "immediate_operand" "i") (sqrt:SF (match_operand:SF 2 "fp_arith_reg_operand" "0")))) - (use (match_operand:PSI 3 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "TARGET_FPU_ANY && TARGET_FSRRA && operands[1] == CONST1_RTX (SFmode)" "fsrra %0" @@ -12864,10 +12843,9 @@ rtx fsca = gen_reg_rtx (V2SFmode); rtx scale_reg = force_reg (SFmode, sh_fsca_sf2int ()); - emit_sf_insn (gen_mulsf3 (scaled, operands[2], scale_reg)); - emit_sf_insn (gen_fix_truncsfsi2 (truncated, scaled)); - emit_sf_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf (), - get_fpscr_rtx ())); + emit_insn (gen_mulsf3 (scaled, operands[2], scale_reg)); + emit_insn (gen_fix_truncsfsi2 (truncated, scaled)); + emit_insn (gen_fsca (fsca, truncated, sh_fsca_int2sf ())); emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, fsca, 4)); emit_move_insn (operands[1], gen_rtx_SUBREG (SFmode, fsca, 0)); @@ -12883,7 +12861,8 @@ ] UNSPEC_FSINA) (unspec:SF [(mult:SF (float:SF (match_dup 1)) (match_dup 2)) ] UNSPEC_FCOSA))) - (use (match_operand:PSI 3 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "TARGET_FPU_ANY && TARGET_FSCA" "fsca fpul,%d0" "&& !fpul_operand (operands[1], SImode)" @@ -12898,9 +12877,8 @@ gcc_assert (GET_CODE (x) == FIX || GET_CODE (x) == FLOAT); x = XEXP (x, 0); } - gcc_assert (x != NULL_RTX && fpul_operand (x, SImode)); - emit_insn (gen_fsca (operands[0], x, operands[2], operands[3])); + emit_insn (gen_fsca (operands[0], x, operands[2])); DONE; } [(set_attr "type" "fsca") @@ -12933,7 +12911,7 @@ { if (TARGET_SH4 || TARGET_SH2A_DOUBLE) { - expand_df_binop (&gen_adddf3_i, operands); + emit_insn (gen_adddf3_i (operands[0], operands[1], operands[2])); DONE; } }) @@ -12950,7 +12928,8 @@ [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") (plus:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0") (match_operand:DF 2 "fp_arith_reg_operand" "f"))) - (use (match_operand:PSI 3 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" "fadd %2,%0" [(set_attr "type" "dfp_arith") @@ -12964,7 +12943,7 @@ { if (TARGET_SH4 || TARGET_SH2A_DOUBLE) { - expand_df_binop (&gen_subdf3_i, operands); + emit_insn (gen_subdf3_i (operands[0], operands[1], operands[2])); DONE; } }) @@ -12981,7 +12960,8 @@ [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") (minus:DF (match_operand:DF 1 "fp_arith_reg_operand" "0") (match_operand:DF 2 "fp_arith_reg_operand" "f"))) - (use (match_operand:PSI 3 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" "fsub %2,%0" [(set_attr "type" "dfp_arith") @@ -12995,7 +12975,7 @@ { if (TARGET_SH4 || TARGET_SH2A_DOUBLE) { - expand_df_binop (&gen_muldf3_i, operands); + emit_insn (gen_muldf3_i (operands[0], operands[1], operands[2])); DONE; } }) @@ -13012,7 +12992,8 @@ [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") (mult:DF (match_operand:DF 1 "fp_arith_reg_operand" "%0") (match_operand:DF 2 "fp_arith_reg_operand" "f"))) - (use (match_operand:PSI 3 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" "fmul %2,%0" [(set_attr "type" "dfp_mul") @@ -13026,7 +13007,7 @@ { if (TARGET_SH4 || TARGET_SH2A_DOUBLE) { - expand_df_binop (&gen_divdf3_i, operands); + emit_insn (gen_divdf3_i (operands[0], operands[1], operands[2])); DONE; } }) @@ -13043,7 +13024,8 @@ [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") (div:DF (match_operand:DF 1 "fp_arith_reg_operand" "0") (match_operand:DF 2 "fp_arith_reg_operand" "f"))) - (use (match_operand:PSI 3 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" "fdiv %2,%0" [(set_attr "type" "dfdiv") @@ -13063,8 +13045,7 @@ { if (TARGET_SH4 || TARGET_SH2A_DOUBLE) { - emit_df_insn (gen_floatsidf2_i (operands[0], operands[1], - get_fpscr_rtx ())); + emit_insn (gen_floatsidf2_i (operands[0], operands[1])); DONE; } }) @@ -13079,7 +13060,8 @@ (define_insn "floatsidf2_i" [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") (float:DF (match_operand:SI 1 "fpul_operand" "y"))) - (use (match_operand:PSI 2 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" "float %1,%0" [(set_attr "type" "dfp_conv") @@ -13099,8 +13081,7 @@ { if (TARGET_SH4 || TARGET_SH2A_DOUBLE) { - emit_df_insn (gen_fix_truncdfsi2_i (operands[0], operands[1], - get_fpscr_rtx ())); + emit_insn (gen_fix_truncdfsi2_i (operands[0], operands[1])); DONE; } }) @@ -13115,40 +13096,20 @@ (define_insn "fix_truncdfsi2_i" [(set (match_operand:SI 0 "fpul_operand" "=y") (fix:SI (match_operand:DF 1 "fp_arith_reg_operand" "f"))) - (use (match_operand:PSI 2 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" "ftrc %1,%0" [(set_attr "type" "dfp_conv") (set_attr "dfp_comp" "no") (set_attr "fp_mode" "double")]) -;; ??? This pattern is used nowhere. fix_truncdfsi2 always expands to -;; fix_truncdfsi2_i. -;; (define_insn "fix_truncdfsi2_i4" -;; [(set (match_operand:SI 0 "arith_reg_operand" "=r") -;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f"))) -;; (use (match_operand:PSI 2 "fpscr_operand" "c")) -;; (clobber (reg:SI FPUL_REG))] -;; "TARGET_SH4" -;; "#" -;; [(set_attr "length" "4") -;; (set_attr "fp_mode" "double")]) -;; -;; (define_split -;; [(set (match_operand:SI 0 "arith_reg_operand" "=r") -;; (fix:SI (match_operand:DF 1 "arith_reg_operand" "f"))) -;; (use (match_operand:PSI 2 "fpscr_operand" "c")) -;; (clobber (reg:SI FPUL_REG))] -;; "TARGET_SH4" -;; [(parallel [(set (reg:SI FPUL_REG) (fix:SI (match_dup 1))) -;; (use (match_dup 2))]) -;; (set (match_dup 0) (reg:SI FPUL_REG))]) - (define_insn "cmpgtdf_t" [(set (reg:SI T_REG) (gt:SI (match_operand:DF 0 "fp_arith_reg_operand" "f") (match_operand:DF 1 "fp_arith_reg_operand" "f"))) - (use (match_operand:PSI 2 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" "fcmp/gt %1,%0" [(set_attr "type" "dfp_cmp") @@ -13158,7 +13119,8 @@ [(set (reg:SI T_REG) (eq:SI (match_operand:DF 0 "fp_arith_reg_operand" "f") (match_operand:DF 1 "fp_arith_reg_operand" "f"))) - (use (match_operand:PSI 2 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" "fcmp/eq %1,%0" [(set_attr "type" "dfp_cmp") @@ -13169,7 +13131,8 @@ (ior:SI (reg:SI T_REG) (eq:SI (match_operand:DF 0 "fp_arith_reg_operand" "f") (match_operand:DF 1 "fp_arith_reg_operand" "f")))) - (use (match_operand:PSI 2 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "TARGET_IEEE && (TARGET_SH4 || TARGET_SH2A_DOUBLE)" { return output_ieee_ccmpeq (insn, operands); @@ -13252,7 +13215,7 @@ { if (TARGET_SH4 || TARGET_SH2A_DOUBLE) { - expand_df_unop (&gen_sqrtdf2_i, operands); + emit_insn (gen_sqrtdf2_i (operands[0], operands[1])); DONE; } }) @@ -13267,7 +13230,8 @@ (define_insn "sqrtdf2_i" [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") (sqrt:DF (match_operand:DF 1 "fp_arith_reg_operand" "0"))) - (use (match_operand:PSI 2 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" "fsqrt %0" [(set_attr "type" "dfdiv") @@ -13299,8 +13263,7 @@ { if (TARGET_SH4 || TARGET_SH2A_DOUBLE) { - emit_df_insn (gen_extendsfdf2_i4 (operands[0], operands[1], - get_fpscr_rtx ())); + emit_insn (gen_extendsfdf2_i4 (operands[0], operands[1])); DONE; } }) @@ -13315,7 +13278,8 @@ (define_insn "extendsfdf2_i4" [(set (match_operand:DF 0 "fp_arith_reg_operand" "=f") (float_extend:DF (match_operand:SF 1 "fpul_operand" "y"))) - (use (match_operand:PSI 2 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" "fcnvsd %1,%0" [(set_attr "type" "fp") @@ -13328,8 +13292,7 @@ { if (TARGET_SH4 || TARGET_SH2A_DOUBLE) { - emit_df_insn (gen_truncdfsf2_i4 (operands[0], operands[1], - get_fpscr_rtx ())); + emit_insn (gen_truncdfsf2_i4 (operands[0], operands[1])); DONE; } }) @@ -13344,7 +13307,8 @@ (define_insn "truncdfsf2_i4" [(set (match_operand:SF 0 "fpul_operand" "=y") (float_truncate:SF (match_operand:DF 1 "fp_arith_reg_operand" "f"))) - (use (match_operand:PSI 2 "fpscr_operand" "c"))] + (clobber (reg:SI FPSCR_STAT_REG)) + (use (reg:SI FPSCR_MODES_REG))] "(TARGET_SH4 || TARGET_SH2A_DOUBLE)" "fcnvds %1,%0" [(set_attr "type" "fp") Index: gcc/config/sh/sh-protos.h =================================================================== --- gcc/config/sh/sh-protos.h (revision 216300) +++ gcc/config/sh/sh-protos.h (working copy) @@ -112,8 +112,6 @@ extern bool sh_legitimize_reload_address (rtx *, enum machine_mode, int, int); extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx); extern bool nonpic_symbol_mentioned_p (rtx); -extern void emit_sf_insn (rtx); -extern void emit_df_insn (rtx); extern void output_pic_addr_const (FILE *, rtx); extern bool expand_block_move (rtx *); extern void prepare_move_operands (rtx[], enum machine_mode mode); @@ -150,10 +148,6 @@ extern enum tls_model tls_symbolic_operand (rtx, enum machine_mode); extern bool system_reg_operand (rtx, enum machine_mode); extern bool reg_unused_after (rtx, rtx_insn *); -extern void expand_sf_unop (rtx (*)(rtx, rtx, rtx), rtx *); -extern void expand_sf_binop (rtx (*)(rtx, rtx, rtx, rtx), rtx *); -extern void expand_df_unop (rtx (*)(rtx, rtx, rtx), rtx *); -extern void expand_df_binop (rtx (*)(rtx, rtx, rtx, rtx), rtx *); extern int sh_insn_length_adjustment (rtx_insn *); extern bool sh_can_redirect_branch (rtx_insn *, rtx_insn *); extern void sh_expand_unop_v2sf (enum rtx_code, rtx, rtx); Index: gcc/testsuite/gcc.target/sh/pr54680.c =================================================================== --- gcc/testsuite/gcc.target/sh/pr54680.c (revision 216300) +++ gcc/testsuite/gcc.target/sh/pr54680.c (working copy) @@ -6,7 +6,7 @@ /* { dg-skip-if "" { "sh*-*-*" } { "-m1" "-m2*" "-m3*" "-m4al" "*nofpu" "-m4-340*" "-m4-400*" "-m4-500*" "-m5*" } { "" } } */ /* { dg-final { scan-assembler-times "fsca" 7 } } */ /* { dg-final { scan-assembler-times "shad" 1 } } */ -/* { dg-final { scan-assembler-times "lds\t" 6 } } */ +/* { dg-final { scan-assembler-times "lds\tr\[0-9\],fpul" 6 } } */ /* { dg-final { scan-assembler-times "fmul" 2 } } */ /* { dg-final { scan-assembler-times "ftrc" 1 } } */