diff options
Diffstat (limited to 'gcc/config/sh/sh.md')
-rw-r--r-- | gcc/config/sh/sh.md | 349 |
1 files changed, 225 insertions, 124 deletions
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 0fe9fca2bed..45a5edf6ad7 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -942,15 +942,10 @@ (set (reg:SI T_REG) (eq:SI (match_dup 4) (match_dup 5))) (match_dup 6)] { - operands[2] - = gen_rtx_REG (SImode, - true_regnum (operands[0]) + (TARGET_LITTLE_ENDIAN ? 1 : 0)); - operands[3] - = (operands[1] == const0_rtx - ? const0_rtx - : gen_rtx_REG (SImode, - true_regnum (operands[1]) - + (TARGET_LITTLE_ENDIAN ? 1 : 0))); + operands[2] = gen_highpart (SImode, operands[0]); + operands[3] = operands[1] == const0_rtx + ? const0_rtx + : gen_highpart (SImode, operands[1]); operands[4] = gen_lowpart (SImode, operands[0]); operands[5] = gen_lowpart (SImode, operands[1]); operands[6] = gen_label_rtx (); @@ -1453,13 +1448,10 @@ "TARGET_SH1 && reload_completed" [(const_int 0)] { - rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]); - high0 = gen_rtx_REG (SImode, - true_regnum (operands[0]) - + (TARGET_LITTLE_ENDIAN ? 1 : 0)); - high2 = gen_rtx_REG (SImode, - true_regnum (operands[2]) - + (TARGET_LITTLE_ENDIAN ? 1 : 0)); + rtx high0 = gen_highpart (SImode, operands[0]); + rtx high2 = gen_highpart (SImode, operands[2]); + rtx low0 = gen_lowpart (SImode, operands[0]); + emit_insn (gen_clrt ()); emit_insn (gen_addc (low0, low0, gen_lowpart (SImode, operands[2]))); emit_insn (gen_addc1 (high0, high0, high2)); @@ -1581,13 +1573,10 @@ "TARGET_SH1 && reload_completed" [(const_int 0)] { - rtx high0, high2, low0 = gen_lowpart (SImode, operands[0]); - high0 = gen_rtx_REG (SImode, - true_regnum (operands[0]) - + (TARGET_LITTLE_ENDIAN ? 1 : 0)); - high2 = gen_rtx_REG (SImode, - true_regnum (operands[2]) - + (TARGET_LITTLE_ENDIAN ? 1 : 0)); + rtx high0 = gen_highpart (SImode, operands[0]); + rtx high2 = gen_highpart (SImode, operands[2]); + rtx low0 = gen_lowpart (SImode, operands[0]); + emit_insn (gen_clrt ()); emit_insn (gen_subc (low0, low0, gen_lowpart (SImode, operands[2]))); emit_insn (gen_subc1 (high0, high0, high2)); @@ -2321,7 +2310,7 @@ norm32: r25 rtx tab_ix = operands[2]; rtx norm32 = operands[3]; rtx scratch0 = operands[4]; - rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF); + rtx scratch0_si = gen_lowpart (SImode, scratch0); rtx scratch1 = operands[5]; emit_insn (gen_divsi_inv_qitable (scratch0, tab_base, tab_ix)); @@ -2368,7 +2357,7 @@ norm32: r25 rtx scratch0b = operands[6]; rtx scratch0 = operands[7]; rtx scratch1 = operands[8]; - rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF); + rtx scratch1_si = gen_lowpart (SImode, scratch1); emit_insn (gen_divsi_inv_m0 (inv0, tab_base, tab_ix, norm32, scratch0a, scratch0b)); @@ -2405,7 +2394,7 @@ norm32: r25 rtx inv1 = operands[2]; rtx i92 = operands[3]; rtx scratch0 = operands[4]; - rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF); + rtx scratch0_si = gen_lowpart (SImode, scratch0); emit_insn (gen_mulsidi3_media (scratch0, inv1, norm32)); emit_insn (gen_ashrdi3_media (scratch0, scratch0, GEN_INT (16))); @@ -2518,9 +2507,9 @@ norm32: r25 rtx i2p27 = operands[7]; rtx i43 = operands[8]; rtx scratch0 = operands[9]; - rtx scratch0_si = simplify_gen_subreg (SImode, scratch0, DImode, SIDI_OFF); + rtx scratch0_si = gen_lowpart (SImode, scratch0); rtx scratch1 = operands[10]; - rtx scratch1_si = simplify_gen_subreg (SImode, scratch1, DImode, SIDI_OFF); + rtx scratch1_si = gen_lowpart (SImode, scratch1); rtx scratch2 = operands[11]; rtx scratch3 = operands[12]; rtx scratch4 = operands[13]; @@ -3919,17 +3908,14 @@ label: (match_operand:DI 2 "const_int_operand" "n")))] "TARGET_SH1 && INTVAL (operands[2]) < 32" { - int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1); - int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0); - rtx low_src = operand_subword (operands[1], low_word, 0, DImode); - rtx high_src = operand_subword (operands[1], high_word, 0, DImode); + rtx low_src = gen_lowpart (SImode, operands[1]); + rtx high_src = gen_highpart (SImode, operands[1]); rtx dst = gen_reg_rtx (DImode); - rtx low_dst = operand_subword (dst, low_word, 1, DImode); - rtx high_dst = operand_subword (dst, high_word, 1, DImode); - rtx tmp0, tmp1; + rtx low_dst = gen_lowpart (SImode, dst); + rtx high_dst = gen_highpart (SImode, dst); + rtx tmp0 = gen_reg_rtx (SImode); + rtx tmp1 = gen_reg_rtx (SImode); - tmp0 = gen_reg_rtx (SImode); - tmp1 = gen_reg_rtx (SImode); emit_insn (gen_lshrsi3 (tmp0, low_src, GEN_INT (32 - INTVAL (operands[2])))); emit_insn (gen_ashlsi3 (low_dst, low_src, operands[2])); emit_insn (gen_ashlsi3 (tmp1, high_src, operands[2])); @@ -4373,14 +4359,10 @@ label: "TARGET_SH1" [(const_int 0)] { - int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1); - int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0); - - rtx low_src = operand_subword (operands[1], low_word, 0, DImode); - rtx high_src = operand_subword (operands[1], high_word, 0, DImode); - - rtx low_dst = operand_subword (operands[0], low_word, 1, DImode); - rtx high_dst = operand_subword (operands[0], high_word, 1, DImode); + rtx low_src = gen_lowpart (SImode, operands[1]); + rtx high_src = gen_highpart (SImode, operands[1]); + rtx low_dst = gen_lowpart (SImode, operands[0]); + rtx high_dst = gen_highpart (SImode, operands[0]); emit_insn (gen_clrt ()); emit_insn (gen_negc (low_dst, low_src)); @@ -4493,8 +4475,7 @@ label: "&& reload_completed" [(const_int 0)] { - int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0); - rtx high_src = operand_subword (operands[1], high_word, 0, DImode); + rtx high_src = gen_highpart (SImode, operands[1]); emit_insn (gen_cmpgesi_t (high_src, const0_rtx)); emit_insn (gen_negdi_cond (operands[0], operands[1], operands[1], const1_rtx)); @@ -4509,9 +4490,7 @@ label: "&& reload_completed" [(const_int 0)] { - int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0); - rtx high_src = operand_subword (operands[1], high_word, 0, DImode); - + rtx high_src = gen_highpart (SImode, operands[1]); emit_insn (gen_cmpgesi_t (high_src, const0_rtx)); emit_insn (gen_negdi_cond (operands[0], operands[1], operands[1], const0_rtx)); @@ -4529,14 +4508,10 @@ label: "TARGET_SH1" [(const_int 0)] { - int low_word = (TARGET_LITTLE_ENDIAN ? 0 : 1); - int high_word = (TARGET_LITTLE_ENDIAN ? 1 : 0); - - rtx low_src = operand_subword (operands[1], low_word, 0, DImode); - rtx high_src = operand_subword (operands[1], high_word, 0, DImode); - - rtx low_dst = operand_subword (operands[0], low_word, 1, DImode); - rtx high_dst = operand_subword (operands[0], high_word, 1, DImode); + rtx low_src = gen_lowpart (SImode, operands[1]); + rtx high_src = gen_highpart (SImode, operands[1]); + rtx low_dst = gen_lowpart (SImode, operands[0]); + rtx high_dst = gen_highpart (SImode, operands[0]); rtx skip_neg_label = gen_label_rtx (); @@ -4768,20 +4743,18 @@ label: operands[1] = XEXP (operands[1], 0); }) +;; FIXME: Maybe fold HImode and QImode stuff with mode iterator? (define_expand "extendhisi2" - [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") - (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "r,m")))] + [(set (match_operand:SI 0 "arith_reg_dest" "") + (sign_extend:SI (match_operand:HI 1 "general_extend_operand" "")))] "" "") -(define_insn "*extendhisi2_compact" - [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") - (sign_extend:SI (match_operand:HI 1 "general_movsrc_operand" "r,m")))] - "TARGET_SH1" - "@ - exts.w %1,%0 - mov.w %1,%0" - [(set_attr "type" "arith,load")]) +(define_expand "extendqisi2" + [(set (match_operand:SI 0 "arith_reg_dest" "") + (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "")))] + "" + "") (define_insn "*extendhisi2_media" [(set (match_operand:SI 0 "register_operand" "=r,r") @@ -4811,12 +4784,6 @@ label: subreg_lowpart_offset (SImode, GET_MODE (op1))); }) -(define_expand "extendqisi2" - [(set (match_operand:SI 0 "arith_reg_dest" "") - (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "")))] - "" - "") - (define_insn "*extendqisi2_compact_reg" [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") (sign_extend:SI (match_operand:QI 1 "register_operand" "r,t")))] @@ -4826,6 +4793,15 @@ label: movt %0" [(set_attr "type" "arith,arith")]) +(define_insn "*extendhisi2_compact_reg" + [(set (match_operand:SI 0 "arith_reg_dest" "=r,r") + (sign_extend:SI (match_operand:HI 1 "register_operand" "r,t")))] + "TARGET_SH1" + "@ + exts.w %1,%0 + movt %0" + [(set_attr "type" "arith,arith")]) + ;; FIXME: Fold non-SH2A and SH2A alternatives with "enabled" attribute. ;; See movqi insns. (define_insn "*extendqisi2_compact_mem_disp" @@ -4833,20 +4809,31 @@ label: (sign_extend:SI (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r") (match_operand:SI 2 "const_int_operand" "K04,N")))))] - "TARGET_SH1 && ! TARGET_SH2A && CONST_OK_FOR_K04 (INTVAL (operands[2]))" + "TARGET_SH1 && ! TARGET_SH2A + && sh_legitimate_index_p (QImode, operands[2], false, true)" "@ mov.b @(%O2,%1),%0 mov.b @%1,%0" [(set_attr "type" "load")]) +(define_insn "*extendhisi2_compact_mem_disp" + [(set (match_operand:SI 0 "arith_reg_dest" "=z,r") + (sign_extend:SI + (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r") + (match_operand:SI 2 "const_int_operand" "K05,N")))))] + "TARGET_SH1 && ! TARGET_SH2A + && sh_legitimate_index_p (HImode, operands[2], false, true)" + "@ + mov.w @(%O2,%1),%0 + mov.w @%1,%0" + [(set_attr "type" "load")]) + (define_insn "*extendqisi2_compact_mem_disp" [(set (match_operand:SI 0 "arith_reg_dest" "=z,r,r") (sign_extend:SI (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,r") (match_operand:SI 2 "const_int_operand" "K04,N,K12")))))] - "TARGET_SH2A - && (CONST_OK_FOR_K04 (INTVAL (operands[2])) - || (CONST_OK_FOR_K12 (INTVAL (operands[2]))))" + "TARGET_SH2A && sh_legitimate_index_p (QImode, operands[2], true, true)" "@ mov.b @(%O2,%1),%0 mov.b @%1,%0 @@ -4854,8 +4841,23 @@ label: [(set_attr "type" "load") (set_attr "length" "2,2,4")]) -;; This will take care of other QImode addressing modes than displacement -;; addressing. +(define_insn "*extendhisi2_compact_mem_disp" + [(set (match_operand:SI 0 "arith_reg_dest" "=z,r,r") + (sign_extend:SI + (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,r") + (match_operand:SI 2 "const_int_operand" "K05,N,K13")))))] + "TARGET_SH2A && sh_legitimate_index_p (HImode, operands[2], true, true)" + "@ + mov.w @(%O2,%1),%0 + mov.w @%1,%0 + mov.w @(%O2,%1),%0" + [(set_attr "type" "load") + (set_attr "length" "2,2,4")]) + +;; The *_snd patterns will take care of other QImode/HImode addressing +;; modes than displacement addressing. They must be defined _after_ the +;; displacement addressing patterns. Otherwise the displacement addressing +;; patterns will not be picked. (define_insn "*extendqisi2_compact_snd" [(set (match_operand:SI 0 "arith_reg_dest" "=r") (sign_extend:SI (match_operand:QI 1 "movsrc_no_disp_mem_operand" "Snd")))] @@ -4863,6 +4865,13 @@ label: "mov.b %1,%0" [(set_attr "type" "load")]) +(define_insn "*extendhisi2_compact_snd" + [(set (match_operand:SI 0 "arith_reg_dest" "=r") + (sign_extend:SI (match_operand:HI 1 "movsrc_no_disp_mem_operand" "Snd")))] + "TARGET_SH1" + "mov.w %1,%0" + [(set_attr "type" "load")]) + (define_insn "*extendqisi2_media" [(set (match_operand:SI 0 "register_operand" "=r,r") (sign_extend:SI (match_operand:QI 1 "general_extend_operand" "r,m")))] @@ -5441,6 +5450,14 @@ label: [(set_attr "type" "sfunc") (set_attr "needs_delay_slot" "yes")]) +(define_expand "movhi" + [(set (match_operand:HI 0 "general_movdst_operand" "") + (match_operand:HI 1 "general_movsrc_operand" ""))] + "" +{ + prepare_move_operands (operands, HImode); +}) + (define_expand "movqi" [(set (match_operand:QI 0 "general_operand" "") (match_operand:QI 1 "general_operand" ""))] @@ -5456,6 +5473,7 @@ label: ;; With the movqi_reg_reg being specified before movqi it will be intially ;; picked to load/store regs. If the regs regs are on the stack reload will ;; try other insns and not stick to movqi_reg_reg. +;; The same applies to the movhi variants. (define_insn "*movqi_reg_reg" [(set (match_operand:QI 0 "arith_reg_dest" "=r,r") (match_operand:QI 1 "register_operand" "r,t"))] @@ -5465,44 +5483,82 @@ label: movt %0" [(set_attr "type" "move,arith")]) +(define_insn "*movhi_reg_reg" + [(set (match_operand:HI 0 "arith_reg_dest" "=r,r") + (match_operand:HI 1 "register_operand" "r,t"))] + "TARGET_SH1" + "@ + mov %1,%0 + movt %0" + [(set_attr "type" "move,arith")]) + ;; FIXME: The non-SH2A and SH2A variants should be combined by adding ;; "enabled" attribute as it is done in other targets. (define_insn "*movqi_store_mem_disp04" [(set (mem:QI (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r,r") (match_operand:SI 1 "const_int_operand" "K04,N"))) (match_operand:QI 2 "arith_reg_operand" "z,r"))] - "TARGET_SH1 && CONST_OK_FOR_K04 (INTVAL (operands[1]))" + "TARGET_SH1 && sh_legitimate_index_p (QImode, operands[1], false, true)" "@ mov.b %2,@(%O1,%0) mov.b %2,@%0" [(set_attr "type" "store")]) +(define_insn "*movhi_store_mem_disp05" + [(set (mem:HI (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r,r") + (match_operand:SI 1 "const_int_operand" "K05,N"))) + (match_operand:HI 2 "arith_reg_operand" "z,r"))] + "TARGET_SH1 && sh_legitimate_index_p (HImode, operands[1], false, true)" + "@ + mov.w %2,@(%O1,%0) + mov.w %2,@%0" + [(set_attr "type" "store")]) + (define_insn "*movqi_store_mem_disp12" [(set (mem:QI (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r") (match_operand:SI 1 "const_int_operand" "K12"))) (match_operand:QI 2 "arith_reg_operand" "r"))] - "TARGET_SH2A && CONST_OK_FOR_K12 (INTVAL (operands[1]))" + "TARGET_SH2A && sh_legitimate_index_p (QImode, operands[1], true, true)" "mov.b %2,@(%O1,%0)" [(set_attr "type" "store") (set_attr "length" "4")]) +(define_insn "*movhi_store_mem_disp13" + [(set (mem:HI (plus:SI (match_operand:SI 0 "arith_reg_operand" "%r") + (match_operand:SI 1 "const_int_operand" "K13"))) + (match_operand:HI 2 "arith_reg_operand" "r"))] + "TARGET_SH2A && sh_legitimate_index_p (HImode, operands[1], true, true)" + "mov.w %2,@(%O1,%0)" + [(set_attr "type" "store") + (set_attr "length" "4")]) + (define_insn "*movqi_load_mem_disp" [(set (match_operand:QI 0 "arith_reg_dest" "=z,r") (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r") (match_operand:SI 2 "const_int_operand" "K04,N"))))] - "TARGET_SH1 && ! TARGET_SH2A && CONST_OK_FOR_K04 (INTVAL (operands[2]))" + "TARGET_SH1 && ! TARGET_SH2A + && sh_legitimate_index_p (QImode, operands[2], false, true)" "@ mov.b @(%O2,%1),%0 mov.b @%1,%0" [(set_attr "type" "load")]) +(define_insn "*movhi_load_mem_disp" + [(set (match_operand:HI 0 "arith_reg_dest" "=z,r") + (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r") + (match_operand:SI 2 "const_int_operand" "K05,N"))))] + "TARGET_SH1 && ! TARGET_SH2A + && sh_legitimate_index_p (HImode, operands[2], false, true)" + "@ + mov.w @(%O2,%1),%0 + mov.w @%1,%0" + [(set_attr "type" "load")]) + (define_insn "*movqi_load_mem_disp" [(set (match_operand:QI 0 "arith_reg_dest" "=z,r,r") (mem:QI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,r") (match_operand:SI 2 "const_int_operand" "K04,N,K12"))))] - "TARGET_SH2A - && (CONST_OK_FOR_K04 (INTVAL (operands[2])) - || CONST_OK_FOR_K12 (INTVAL (operands[2])))" + "TARGET_SH2A && sh_legitimate_index_p (QImode, operands[2], true, true)" "@ mov.b @(%O2,%1),%0 mov.b @%1,%0 @@ -5510,6 +5566,18 @@ label: [(set_attr "type" "load") (set_attr "length" "2,2,4")]) +(define_insn "*movhi_load_mem_disp" + [(set (match_operand:HI 0 "arith_reg_dest" "=z,r,r") + (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "%r,r,r") + (match_operand:SI 2 "const_int_operand" "K05,N,K13"))))] + "TARGET_SH2A && sh_legitimate_index_p (HImode, operands[2], true, true)" + "@ + mov.w @(%O2,%1),%0 + mov.w @%1,%0 + mov.w @(%O2,%1),%0" + [(set_attr "type" "load") + (set_attr "length" "2,2,4")]) + ;; The m constraints basically allow any kind of addresses to be used with any ;; source/target register as the other operand. This is not true for ;; displacement addressing modes on anything but SH2A. That's why the @@ -5528,6 +5596,21 @@ label: lds %1,%0" [(set_attr "type" "movi8,load,store,prget,prset")]) +(define_insn "*movhi" + [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,m,r,l") + (match_operand:HI 1 "general_movsrc_operand" "Q,i,m,r,l,r"))] + "TARGET_SH1 + && (arith_reg_operand (operands[0], HImode) + || arith_reg_operand (operands[1], HImode))" + "@ + mov.w %1,%0 + mov %1,%0 + mov.w %1,%0 + mov.w %1,%0 + sts %1,%0 + lds %1,%0" + [(set_attr "type" "pcload,movi8,load,store,prget,prset")]) + (define_insn "*movqi_media" [(set (match_operand:QI 0 "general_movdst_operand" "=r,r,r,m") (match_operand:QI 1 "general_movsrc_operand" "r,I16Css,m,rZ"))] @@ -5560,28 +5643,6 @@ label: operands[3] = gen_rtx_REG (DImode, REGNO (operands[2])); }) -;; When storing r0, we have to avoid reg+reg addressing. -(define_insn "movhi_i" - [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m,r,l,r") - (match_operand:HI 1 "general_movsrc_operand" "Q,rI08,m,t,r,l,r,i"))] - "TARGET_SH1 - && (arith_reg_operand (operands[0], HImode) - || arith_reg_operand (operands[1], HImode)) - && (!MEM_P (operands[0]) - || GET_CODE (XEXP (operands[0], 0)) != PLUS - || !REG_P (XEXP (XEXP (operands[0], 0), 1)) - || ! refers_to_regno_p (R0_REG, R0_REG + 1, operands[1], (rtx *)0))" - "@ - mov.w %1,%0 - mov %1,%0 - mov.w %1,%0 - movt %0 - mov.w %1,%0 - sts %1,%0 - lds %1,%0 - fake %1,%0" - [(set_attr "type" "pcload,move,load,move,store,move,move,pcload")]) - (define_insn "*movhi_media" [(set (match_operand:HI 0 "general_movdst_operand" "=r,r,r,r,m") (match_operand:HI 1 "general_movsrc_operand" "r,I16Css,n,m,rZ"))] @@ -5607,14 +5668,6 @@ label: && ! satisfies_constraint_I16 (operands[1])" [(set (subreg:DI (match_dup 0) 0) (match_dup 1))]) -(define_expand "movhi" - [(set (match_operand:HI 0 "general_movdst_operand" "") - (match_operand:HI 1 "general_movsrc_operand" ""))] - "" -{ - prepare_move_operands (operands, HImode); -}) - (define_expand "reload_inhi" [(set (match_operand:SI 2 "" "=&r") (match_operand:HI 1 "inqhi_operand" "")) @@ -11563,10 +11616,10 @@ label: ;; Fold sequence: ;; mov #54,r0 -;; mov.b @(r0,r15),r0 +;; mov.{b,w} @(r0,r15),r0 ;; mov r0,r3 ;; into: -;; mov.b @(54,r15),r3 +;; mov.{b,w} @(54,r15),r3 ;; (define_peephole2 [(set (match_operand:SI 0 "arith_reg_dest" "") @@ -11578,17 +11631,33 @@ label: (set (match_operand:QI 4 "arith_reg_dest" "") (match_operand:QI 5 "arith_reg_operand" ""))] "TARGET_SH2A - && CONST_OK_FOR_K12 (INTVAL (operands[1])) + && sh_legitimate_index_p (QImode, operands[1], true, true) && REGNO (operands[2]) == REGNO (operands[5]) && peep2_reg_dead_p (3, operands[5])" [(set (match_dup 4) (mem:QI (plus:SI (match_dup 3) (match_dup 1))))] "") +(define_peephole2 + [(set (match_operand:SI 0 "arith_reg_dest" "") + (match_operand:SI 1 "const_int_operand" "")) + (set (match_operand:SI 2 "arith_reg_dest" "") + (sign_extend:SI + (mem:HI (plus:SI (match_dup 0) + (match_operand:SI 3 "arith_reg_operand" ""))))) + (set (match_operand:HI 4 "arith_reg_dest" "") + (match_operand:HI 5 "arith_reg_operand" ""))] + "TARGET_SH2A + && sh_legitimate_index_p (HImode, operands[1], true, true) + && REGNO (operands[2]) == REGNO (operands[5]) + && peep2_reg_dead_p (3, operands[5])" + [(set (match_dup 4) (mem:HI (plus:SI (match_dup 3) (match_dup 1))))] + "") + ;; Fold sequence: ;; mov #54,r0 -;; mov.b @(r0,r15),r1 +;; mov.{b,w} @(r0,r15),r1 ;; into: -;; mov.b @(54,r15),r1 +;; mov.{b,w} @(54,r15),r1 ;; (define_peephole2 [(set (match_operand:SI 0 "arith_reg_dest" "") @@ -11598,19 +11667,37 @@ label: (mem:QI (plus:SI (match_dup 0) (match_operand:SI 3 "arith_reg_operand" "")))))] "TARGET_SH2A - && CONST_OK_FOR_K12 (INTVAL (operands[1])) + && sh_legitimate_index_p (QImode, operands[1], true, true) && (peep2_reg_dead_p (2, operands[0]) || REGNO (operands[0]) == REGNO (operands[2]))" [(set (match_dup 2) (sign_extend:SI (mem:QI (plus:SI (match_dup 3) (match_dup 1)))))] "") +(define_peephole2 + [(set (match_operand:SI 0 "arith_reg_dest" "") + (match_operand:SI 1 "const_int_operand" "")) + (set (match_operand:SI 2 "arith_reg_dest" "") + (sign_extend:SI + (mem:HI (plus:SI (match_dup 0) + (match_operand:SI 3 "arith_reg_operand" "")))))] + "TARGET_SH2A + && sh_legitimate_index_p (HImode, operands[1], true, true) + && (peep2_reg_dead_p (2, operands[0]) + || REGNO (operands[0]) == REGNO (operands[2]))" + [(set (match_dup 2) + (sign_extend:SI (mem:HI (plus:SI (match_dup 3) (match_dup 1)))))] + "") + ;; Fold sequence: -;; mov.b @(r0,r15),r0 +;; mov.{b,w} @(r0,r15),r0 ;; mov r0,r3 ;; into: -;; mov.b @(r0,r15),r3 +;; mov.{b,w} @(r0,r15),r3 ;; +;; This can happen when initially a displacement address is picked, where +;; the destination reg is fixed to r0, and then the address is transformed +;; into 'r0 + reg'. (define_peephole2 [(set (match_operand:SI 0 "arith_reg_dest" "") (sign_extend:SI @@ -11625,6 +11712,20 @@ label: (mem:QI (plus:SI (match_dup 1) (match_dup 2))))] "") +(define_peephole2 + [(set (match_operand:SI 0 "arith_reg_dest" "") + (sign_extend:SI + (mem:HI (plus:SI (match_operand:SI 1 "arith_reg_operand" "") + (match_operand:SI 2 "arith_reg_operand" ""))))) + (set (match_operand:HI 3 "arith_reg_dest" "") + (match_operand:HI 4 "arith_reg_operand" ""))] + "TARGET_SH1 + && REGNO (operands[0]) == REGNO (operands[4]) + && peep2_reg_dead_p (2, operands[0])" + [(set (match_dup 3) + (mem:HI (plus:SI (match_dup 1) (match_dup 2))))] + "") + ;; These convert sequences such as `mov #k,r0; add r15,r0; mov.l @r0,rn' ;; to `mov #k,r0; mov.l @(r0,r15),rn'. These sequences are generated by ;; reload when the constant is too large for a reg+offset address. |