From 6efc6b7f05d7ea5bae0fb18dd2c8cec4aa69eb48 Mon Sep 17 00:00:00 2001 From: Kaz Kojima Date: Fri, 19 Dec 2014 04:51:53 +0000 Subject: [PATCH] * [SH] Modify movsi_ie and movsf_ie patterns for LRA. From-SVN: r218890 --- gcc/ChangeLog | 10 ++++ gcc/config/sh/sh-protos.h | 1 + gcc/config/sh/sh.c | 29 ++++++++++ gcc/config/sh/sh.md | 110 +++++++++++++++++++++++++++++++++++++- 4 files changed, 148 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2753fae33b2..255b8dbd61f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2014-12-19 Kaz Kojima + + * config/sh/sh-protos.h (sh_movsf_ie_ra_split_p): Declare. + * config/sh/sh.c (sh_movsf_ie_ra_split_p): New function. + * config/sh/sh.md (movsi_ie): Use "mr" constraint for the 8-th + altarnative of operand 0. + (movesf_ie): Use "X" constraint instead of "Bsc". + (movsf_ie_ra): New insn_and_split. + (movsf): Use movsfie_ra when lra_in_progress is true. + 2014-12-19 Kaz Kojima * config/sh/predicates.md (general_movsrc_operand): Allow only diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h index 7697c4cbe0b..b0fc67a07b9 100644 --- a/gcc/config/sh/sh-protos.h +++ b/gcc/config/sh/sh-protos.h @@ -159,6 +159,7 @@ extern rtx sh_find_equiv_gbr_addr (rtx_insn* cur_insn, rtx mem); extern int sh_eval_treg_value (rtx op); extern HOST_WIDE_INT sh_disp_addr_displacement (rtx mem_op); extern int sh_max_mov_insn_displacement (machine_mode mode, bool consider_sh2a); +extern bool sh_movsf_ie_ra_split_p (rtx, rtx, rtx); /* Result value of sh_find_set_of_reg. */ struct set_of_reg diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index b01efb09d3f..7851fe86863 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -13291,6 +13291,35 @@ sh_legitimize_address_displacement (rtx *disp, rtx *offs, return false; } +/* Return true if movsf insn should be splited with an additional + register. */ +bool +sh_movsf_ie_ra_split_p (rtx op0, rtx op1, rtx op2) +{ + /* op0 == op1 */ + if (rtx_equal_p (op0, op1)) + return true; + /* fy, FQ, reg */ + if (GET_CODE (op1) == CONST_DOUBLE + && ! satisfies_constraint_G (op1) + && ! satisfies_constraint_H (op1) + && REG_P (op0) + && REG_P (op2)) + return true; + /* f, r, y */ + if (REG_P (op0) && FP_REGISTER_P (REGNO (op0)) + && REG_P (op1) && GENERAL_REGISTER_P (REGNO (op1)) + && REG_P (op2) && (REGNO (op2) == FPUL_REG)) + return true; + /* r, f, y */ + if (REG_P (op1) && FP_REGISTER_P (REGNO (op1)) + && REG_P (op0) && GENERAL_REGISTER_P (REGNO (op0)) + && REG_P (op2) && (REGNO (op2) == FPUL_REG)) + return true; + + return false; +} + static void sh_conditional_register_usage (void) { diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 536a4989665..76f5c4ad1ab 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -6665,7 +6665,7 @@ label: ;; TARGET_FMOVD is in effect, and mode switching is done before reload. (define_insn "movsi_ie" [(set (match_operand:SI 0 "general_movdst_operand" - "=r,r,r,r,r,r,r,r,m,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y") + "=r,r,r,r,r,r,r,r,mr,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y") (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) @@ -8329,7 +8329,7 @@ label: (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 (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"))] + (clobber (match_scratch:SI 2 "=X,X,X,X,&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) @@ -8409,6 +8409,104 @@ label: (const_string "none") (const_string "none")])]) +(define_insn_and_split "movsf_ie_ra" + [(set (match_operand:SF 0 "general_movdst_operand" + "=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,m,f,FQ,m,r,y,f,>,fr,y,r,y,>,y")) + (use (reg:SI FPSCR_MODES_REG)) + (clobber (match_scratch:SF 2 "=r,r,X,X,&z,r,r,X,r,r,r,r,r,y,r,r,r,r,r")) + (const_int 0)] + "TARGET_SH2E + && (arith_reg_operand (operands[0], SFmode) + || fpul_operand (operands[0], SFmode) + || arith_reg_operand (operands[1], SFmode) + || fpul_operand (operands[1], SFmode))" + "@ + fmov %1,%0 + mov %1,%0 + fldi0 %0 + fldi1 %0 + # + fmov.s %1,%0 + fmov.s %1,%0 + mov.l %1,%0 + mov.l %1,%0 + mov.l %1,%0 + fsts fpul,%0 + flds %1,fpul + lds.l %1,%0 + # + sts %1,%0 + lds %1,%0 + sts.l %1,%0 + lds.l %1,%0 + ! move optimized away" + "reload_completed + && sh_movsf_ie_ra_split_p (operands[0], operands[1], operands[2])" + [(const_int 0)] +{ + if (! rtx_equal_p (operands[0], operands[1])) + { + emit_insn (gen_movsf_ie (operands[2], operands[1])); + emit_insn (gen_movsf_ie (operands[0], operands[2])); + } +} + [(set_attr "type" "fmove,move,fmove,fmove,pcfload,fload,fstore,pcload,load, + store,fmove,fmove,load,*,fpul_gp,gp_fpul,fstore,load,nil") + (set_attr "late_fp_use" "*,*,*,*,*,*,yes,*,*,*,*,*,*,*,yes,*,yes,*,*") + (set_attr_alternative "length" + [(const_int 2) + (const_int 2) + (const_int 2) + (const_int 2) + (const_int 4) + (if_then_else + (match_test "TARGET_SH2A") + (const_int 4) (const_int 2)) + (if_then_else + (match_test "TARGET_SH2A") + (const_int 4) (const_int 2)) + (const_int 2) + (if_then_else + (match_test "TARGET_SH2A") + (const_int 4) (const_int 2)) + (if_then_else + (match_test "TARGET_SH2A") + (const_int 4) (const_int 2)) + (const_int 2) + (const_int 2) + (const_int 2) + (const_int 4) + (const_int 2) + (const_int 2) + (const_int 2) + (const_int 2) + (const_int 0)]) + (set_attr_alternative "fp_mode" + [(if_then_else (eq_attr "fmovd" "yes") + (const_string "single") (const_string "none")) + (const_string "none") + (const_string "single") + (const_string "single") + (const_string "none") + (if_then_else (eq_attr "fmovd" "yes") + (const_string "single") (const_string "none")) + (if_then_else (eq_attr "fmovd" "yes") + (const_string "single") (const_string "none")) + (const_string "none") + (const_string "none") + (const_string "none") + (const_string "none") + (const_string "none") + (const_string "none") + (const_string "none") + (const_string "none") + (const_string "none") + (const_string "none") + (const_string "none") + (const_string "none")])]) + (define_split [(set (match_operand:SF 0 "register_operand" "") (match_operand:SF 1 "register_operand" "")) @@ -8439,6 +8537,14 @@ label: } if (TARGET_SH2E) { + if (lra_in_progress) + { + if (GET_CODE (operands[0]) == SCRATCH) + DONE; + emit_insn (gen_movsf_ie_ra (operands[0], operands[1])); + DONE; + } + emit_insn (gen_movsf_ie (operands[0], operands[1])); DONE; } -- 2.30.2