diff options
author | Jim Wilson <wilson@gcc.gnu.org> | 1996-01-18 14:37:48 -0800 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 1996-01-18 14:37:48 -0800 |
commit | 45348d9eef411416a63d4de1587faf21b2b3d812 (patch) | |
tree | 3ff805588c5c6567de97f6e0f060899ed459a84e | |
parent | 47fd14f4dfebde589696dd546f81b024206cc489 (diff) | |
download | gcc-45348d9eef411416a63d4de1587faf21b2b3d812.zip gcc-45348d9eef411416a63d4de1587faf21b2b3d812.tar.gz gcc-45348d9eef411416a63d4de1587faf21b2b3d812.tar.bz2 |
(cpu, movsi_i, movsf_i, blt, bge, sle, sge): Add SH3E support.
(cpu, movsi_i, movsf_i, blt, bge, sle, sge): Add SH3E
support.
(push_e, pop_e, movsi_ie, movsf_ie, addsf3, subsf3, mulsf3, macsf3,
divsf3, floatsisf2, fix_truncsfsi2, cmpgtsf_t, cmpqesf_t, cmpsf,
negsf2, sqrtsf2, abssf2): New patterns.
(abssf2+9, abssf2+10): Add SH3e support to peepholes
(abssf2+11, abssf2+12): New peepholes for SH3e.
From-SVN: r11065
-rw-r--r-- | gcc/config/sh/sh.md | 307 |
1 files changed, 296 insertions, 11 deletions
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 898b508..908d5c2 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -73,7 +73,7 @@ ;; Target CPU. -(define_attr "cpu" "sh0,sh1,sh2,sh3" +(define_attr "cpu" "sh0,sh1,sh2,sh3,sh3e" (const (symbol_ref "sh_cpu_attr"))) ;; cbranch conditional branch instructions @@ -142,6 +142,8 @@ (define_function_unit "mpy" 1 0 (eq_attr "type" "smpy") 2 2) (define_function_unit "mpy" 1 0 (eq_attr "type" "dmpy") 3 3) +;; ??? Must define SH3E function units. + ; Definitions for filling branch delay slots. (define_attr "needs_delay_slot" "yes,no" (const_string "no")) @@ -1130,6 +1132,28 @@ [(set_attr "type" "load,pload,load") (set_attr "hit_stack" "yes")]) +(define_insn "push_e" + [(set (mem:SF (pre_dec:SI (reg:SI 15))) + (match_operand:SF 0 "register_operand" "r,f,y"))] + "" + "@ + mov.l %0,@-r15 + fmov.s %0,@-r15 + sts.l %0,@-r15" + [(set_attr "type" "store") + (set_attr "hit_stack" "yes")]) + +(define_insn "pop_e" + [(set (match_operand:SF 0 "register_operand" "=r,f,y") + (mem:SF (post_inc:SI (reg:SI 15))))] + "" + "@ + mov.l @r15+,%0 + fmov.s @r15+,%0 + lds.l @r15+,%0" + [(set_attr "type" "load") + (set_attr "hit_stack" "yes")]) + ;; These two patterns can happen as the result of optimization, when ;; comparisons get simplified to a move of zero or 1 into the T reg. ;; They don't disappear completely, because the T reg is a fixed hard reg. @@ -1149,8 +1173,10 @@ (define_insn "movsi_i" [(set (match_operand:SI 0 "general_movdst_operand" "=t,r,r,r,r,r,m,<,xl,xl,r") (match_operand:SI 1 "general_movsrc_operand" "z,Q,rI,m,xl,t,r,xl,r,>,i"))] - "register_operand (operands[0], SImode) - || register_operand (operands[1], SImode)" + " + ! TARGET_SH3E && + (register_operand (operands[0], SImode) + || register_operand (operands[1], SImode))" "@ tst %1,%1\;rotcl %1\;xor #1,%1\;rotcr %1 mov.l %1,%0 @@ -1166,6 +1192,33 @@ [(set_attr "type" "move,pcload,move,load,move,store,store,move,load,move,move") (set_attr "length" "8,*,*,*,*,*,*,*,*,*,*")]) +;; t/z is first, so that it will be preferred over r/r when reloading a move +;; of a pseudo-reg into the T reg +;; ??? This allows moves from macl to fpul to be recognized, but these moves +;; will require a reload. +(define_insn "movsi_ie" + [(set (match_operand:SI 0 "general_movdst_operand" "=t,r,r,r,r,r,m,<,xl,xl,r,y,r") + (match_operand:SI 1 "general_movsrc_operand" "z,Q,rI,m,xl,t,r,xl,r,>,i,r,y"))] + "TARGET_SH3E + && (register_operand (operands[0], SImode) + || register_operand (operands[1], SImode))" + "@ + tst %1,%1\;rotcl %1\;xor #1,%1\;rotcr %1 + mov.l %1,%0 + mov %1,%0 + mov.l %1,%0 + sts %1,%0 + movt %0 + mov.l %1,%0 + sts.l %1,%0 + lds %1,%0 + lds.l %1,%0 + fake %1,%0 + lds %1,%0 + sts %1,%0" + [(set_attr "type" "move,pcload,move,load,move,store,store,move,load,move,move,move,move") + (set_attr "length" "8,*,*,*,*,*,*,*,*,*,*,*,*")]) + (define_expand "movsi" [(set (match_operand:SI 0 "general_movdst_operand" "") (match_operand:SI 1 "general_movsrc_operand" ""))] @@ -1345,8 +1398,10 @@ (define_insn "movsf_i" [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,m,l,r") (match_operand:SF 1 "general_movsrc_operand" "r,I,m,r,r,l"))] - "arith_reg_operand (operands[0], SFmode) - || arith_reg_operand (operands[1], SFmode)" + " + ! TARGET_SH3E && + (arith_reg_operand (operands[0], SFmode) + || arith_reg_operand (operands[1], SFmode))" "@ mov %1,%0 mov %1,%0 @@ -1356,6 +1411,26 @@ sts %1,%0" [(set_attr "type" "move,move,load,store,move,move")]) +(define_insn "movsf_ie" + [(set (match_operand:SF 0 "general_movdst_operand" "=f,r,f,f,f,m,r,m,!r,!f") + (match_operand:SF 1 "general_movsrc_operand" "f,r,G,H,m,f,m,r,f,r"))] + "TARGET_SH3E + && (arith_reg_operand (operands[0], SFmode) + || arith_reg_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 + flds %1,fpul\;sts fpul,%0 + lds %1,fpul\;fsts fpul,%0" + [(set_attr "type" "move,move,move,move,load,store,load,store,move,move") + (set_attr "length" "*,*,*,*,*,*,*,*,4,4")]) + (define_expand "movsf" [(set (match_operand:SF 0 "general_movdst_operand" "") (match_operand:SF 1 "general_movsrc_operand" ""))] @@ -1436,7 +1511,18 @@ (pc) (label_ref (match_operand 0 "" ""))))] "" - "from_compare (operands, LT);") + " +{ + if (GET_MODE (sh_compare_op0) == SFmode) + { + rtx tmp = sh_compare_op0; + sh_compare_op0 = sh_compare_op1; + sh_compare_op1 = tmp; + emit_insn (gen_bgt (operands[0])); + DONE; + } + from_compare (operands, LT); +}") (define_expand "ble" [(set (reg:SI 18) (gt:SI (match_dup 1) (match_dup 2))) @@ -1454,7 +1540,18 @@ (label_ref (match_operand 0 "" "")) (pc)))] "" - "from_compare (operands, GE);") + " +{ + if (GET_MODE (sh_compare_op0) == SFmode) + { + rtx tmp = sh_compare_op0; + sh_compare_op0 = sh_compare_op1; + sh_compare_op1 = tmp; + emit_insn (gen_ble (operands[0])); + DONE; + } + from_compare (operands, GE); +}") (define_expand "bgtu" [(set (reg:SI 18) (gtu:SI (match_dup 1) (match_dup 2))) @@ -1691,7 +1788,16 @@ [(set (match_operand:SI 0 "arith_reg_operand" "") (match_dup 1))] "" - "operands[1] = prepare_scc_operands (LE);") + " +{ + if (GET_MODE (sh_compare_op0) == SFmode) + { + emit_insn (gen_sgt (operands[0])); + emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx)); + DONE; + } + operands[1] = prepare_scc_operands (LE); +}") (define_expand "sgt" [(set (match_operand:SI 0 "arith_reg_operand" "") @@ -1703,7 +1809,16 @@ [(set (match_operand:SI 0 "arith_reg_operand" "") (match_dup 1))] "" - "operands[1] = prepare_scc_operands (GE);") + " +{ + if (GET_MODE (sh_compare_op0) == SFmode) + { + emit_insn (gen_slt (operands[0])); + emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx)); + DONE; + } + operands[1] = prepare_scc_operands (GE); +}") (define_expand "sgtu" [(set (match_operand:SI 0 "arith_reg_operand" "") @@ -1853,7 +1968,144 @@ "jsr @%0%#" [(set_attr "type" "sfunc") (set_attr "needs_delay_slot" "yes")]) + +;; ------------------------------------------------------------------------- +;; Floating point instructions. +;; ------------------------------------------------------------------------- + +;; ??? All patterns should have a type attribute. + +(define_insn "addsf3" + [(set (match_operand:SF 0 "arith_reg_operand" "=f") + (plus:SF (match_operand:SF 1 "arith_reg_operand" "%0") + (match_operand:SF 2 "arith_reg_operand" "f")))] + "TARGET_SH3E" + "fadd %2,%0") + +(define_insn "subsf3" + [(set (match_operand:SF 0 "arith_reg_operand" "=f") + (minus:SF (match_operand:SF 1 "arith_reg_operand" "0") + (match_operand:SF 2 "arith_reg_operand" "f")))] + "TARGET_SH3E" + "fsub %2,%0") + +(define_insn "mulsf3" + [(set (match_operand:SF 0 "arith_reg_operand" "=f") + (mult:SF (match_operand:SF 1 "arith_reg_operand" "%0") + (match_operand:SF 2 "arith_reg_operand" "f")))] + "TARGET_SH3E" + "fmul %2,%0") + +(define_insn "*macsf3" + [(set (match_operand:SF 0 "arith_reg_operand" "=f") + (plus:SF (mult:SF (match_operand:SF 1 "arith_reg_operand" "%w") + (match_operand:SF 2 "arith_reg_operand" "f")) + (match_operand:SF 3 "arith_reg_operand" "0")))] + "TARGET_SH3E" + "fmac fr0,%2,%0") + +(define_insn "divsf3" + [(set (match_operand:SF 0 "arith_reg_operand" "=f") + (div:SF (match_operand:SF 1 "arith_reg_operand" "0") + (match_operand:SF 2 "arith_reg_operand" "f")))] + "TARGET_SH3E" + "fdiv %2,%0") + +;; ??? This is the right solution, but it fails because the movs[if] patterns +;; silently clobber FPUL (r22) for int<->fp moves. Thus we can not explicitly +;; use FPUL here. +;; +;;(define_expand "floatsisf2" +;; [(set (reg:SI 22) +;; (match_operand:SI 1 "arith_reg_operand" "")) +;; (set (match_operand:SF 0 "arith_reg_operand" "") +;; (float:SF (reg:SI 22)))] +;; "TARGET_SH3E" +;; "") +;; +;;(define_insn "*floatsisf" +;; [(set (match_operand:SF 0 "arith_reg_operand" "=f") +;; (float:SF (reg:SI 22)))] +;; "TARGET_SH3E" +;; "float fpul,%0") + +(define_insn "floatsisf2" + [(set (match_operand:SF 0 "arith_reg_operand" "=f") + (float:SF (match_operand:SI 1 "arith_reg_operand" "r")))] + "TARGET_SH3E" + "lds %1,fpul\;float fpul,%0" + [(set_attr "length" "4")]) + +;; ??? This is the right solution, but it fails because the movs[if] patterns +;; silently clobber FPUL (r22) for int<->fp moves. Thus we can not explicitly +;; use FPUL here. +;; +;;(define_expand "fix_truncsfsi2" +;; [(set (reg:SI 22) +;; (fix:SI (match_operand:SF 1 "arith_reg_operand" "f"))) +;; (set (match_operand:SI 0 "arith_reg_operand" "=r") +;; (reg:SI 22))] +;; "TARGET_SH3E" +;; "") +;; +;;(define_insn "*fixsfsi" +;; [(set (reg:SI 22) +;; (fix:SI (match_operand:SF 0 "arith_reg_operand" "f")))] +;; "TARGET_SH3E" +;; "ftrc %0,fpul") + +(define_insn "fix_truncsfsi2" + [(set (match_operand:SI 0 "arith_reg_operand" "=r") + (fix:SI (match_operand:SF 1 "arith_reg_operand" "f")))] + "TARGET_SH3E" + "ftrc %1,fpul\;sts fpul,%0" + [(set_attr "length" "4")]) + +;; ??? This should be SFmode not SImode in the compare, but that would +;; require fixing the branch patterns too. +(define_insn "*cmpgtsf_t" + [(set (reg:SI 18) (gt:SI (match_operand:SF 0 "arith_reg_operand" "f") + (match_operand:SF 1 "arith_reg_operand" "f")))] + "TARGET_SH3E" + "fcmp/gt %1,%0") + +;; ??? This should be SFmode not SImode in the compare, but that would +;; require fixing the branch patterns too. +(define_insn "*cmpeqsf_t" + [(set (reg:SI 18) (eq:SI (match_operand:SF 0 "arith_reg_operand" "f") + (match_operand:SF 1 "arith_reg_operand" "f")))] + "TARGET_SH3E" + "fcmp/eq %1,%0") + +(define_expand "cmpsf" + [(set (reg:SI 18) (compare (match_operand:SF 0 "arith_operand" "") + (match_operand:SF 1 "arith_operand" "")))] + "TARGET_SH3E" + " +{ + sh_compare_op0 = operands[0]; + sh_compare_op1 = operands[1]; + DONE; +}") +(define_insn "negsf2" + [(set (match_operand:SF 0 "arith_reg_operand" "=f") + (neg:SF (match_operand:SF 1 "arith_reg_operand" "0")))] + "TARGET_SH3E" + "fneg %0") + +(define_insn "sqrtsf2" + [(set (match_operand:SF 0 "arith_reg_operand" "=f") + (sqrt:DF (match_operand:SF 1 "arith_reg_operand" "0")))] + "TARGET_SH3E" + "fsqrt %0") + +(define_insn "abssf2" + [(set (match_operand:SF 0 "arith_reg_operand" "=f") + (abs:SF (match_operand:SF 1 "arith_reg_operand" "0")))] + "TARGET_SH3E" + "fabs %0") + ;; ------------------------------------------------------------------------- ;; Peepholes ;; ------------------------------------------------------------------------- @@ -1949,7 +2201,11 @@ (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) (set (mem:SF (match_dup 0)) (match_operand:SF 2 "general_movsrc_operand" ""))] - "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)" + "REGNO (operands[0]) == 0 + && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16) + || (GET_CODE (operands[2]) == SUBREG + && REGNO (SUBREG_REG (operands[2])) < 16)) + && reg_unused_after (operands[0], insn)" "mov.l %2,@(%0,%1)") (define_peephole @@ -1958,5 +2214,34 @@ (set (match_operand:SF 2 "general_movdst_operand" "") (mem:SF (match_dup 0)))] - "REGNO (operands[0]) == 0 && reg_unused_after (operands[0], insn)" + "REGNO (operands[0]) == 0 + && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) < 16) + || (GET_CODE (operands[2]) == SUBREG + && REGNO (SUBREG_REG (operands[2])) < 16)) + && reg_unused_after (operands[0], insn)" "mov.l @(%0,%1),%2") + +(define_peephole + [(set (match_operand:SI 0 "register_operand" "=r") + (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) + (set (mem:SF (match_dup 0)) + (match_operand:SF 2 "general_movsrc_operand" ""))] + "REGNO (operands[0]) == 0 + && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) >= FIRST_FP_REG) + || (GET_CODE (operands[2]) == SUBREG + && REGNO (SUBREG_REG (operands[2])) >= FIRST_FP_REG)) + && reg_unused_after (operands[0], insn)" + "fmov.s %2,@(%0,%1)") + +(define_peephole + [(set (match_operand:SI 0 "register_operand" "=r") + (plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r"))) + (set (match_operand:SF 2 "general_movdst_operand" "") + + (mem:SF (match_dup 0)))] + "REGNO (operands[0]) == 0 + && ((GET_CODE (operands[2]) == REG && REGNO (operands[2]) >= FIRST_FP_REG) + || (GET_CODE (operands[2]) == SUBREG + && REGNO (SUBREG_REG (operands[2])) >= FIRST_FP_REG)) + && reg_unused_after (operands[0], insn)" + "fmov.s @(%0,%1),%2") |