diff options
author | Jim Wilson <wilson@gcc.gnu.org> | 1996-09-16 10:39:15 -0700 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 1996-09-16 10:39:15 -0700 |
commit | 98e819b9b7517686db6f7a313a25e13486e4563c (patch) | |
tree | 6b8bd3ca4436a8c950f542ad803b40bb6b127a7c /gcc/config/sh | |
parent | e0040a8ede6f15e54a55e9e7bdddf6a66bffec2a (diff) | |
download | gcc-98e819b9b7517686db6f7a313a25e13486e4563c.zip gcc-98e819b9b7517686db6f7a313a25e13486e4563c.tar.gz gcc-98e819b9b7517686db6f7a313a25e13486e4563c.tar.bz2 |
(ashlhi3_k, lshrhi3_m): new insn pattern.
(lshrhi3, shl_sext_ext, shl_sext_sub):
new insn pattern with matching define_split.
(and_shl_scratch): Likewise, but also with unnamed variants.
From-SVN: r12725
Diffstat (limited to 'gcc/config/sh')
-rw-r--r-- | gcc/config/sh/sh.md | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 2371bf3..9e9fd94 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -783,6 +783,15 @@ add %0,%0 shll%O2 %0") +(define_insn "ashlhi3_k" + [(set (match_operand:HI 0 "arith_reg_operand" "=r,r") + (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0,0") + (match_operand:HI 2 "const_int_operand" "M,K")))] + "CONST_OK_FOR_K (INTVAL (operands[2]))" + "@ + add %0,%0 + shll%O2 %0") + (define_insn "ashlsi3_n" [(set (match_operand:SI 0 "arith_reg_operand" "=r") (ashift:SI (match_operand:SI 1 "arith_reg_operand" "0") @@ -830,6 +839,34 @@ FAIL; }") +(define_insn "ashlhi3" + [(set (match_operand:HI 0 "arith_reg_operand" "=r") + (ashift:HI (match_operand:HI 1 "arith_reg_operand" "0") + (match_operand:HI 2 "const_int_operand" "n"))) + (clobber (reg:SI 18))] + "" + "#" + [(set (attr "length") + (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1)) + (const_string "2") + (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2)) + (const_string "4")] + (const_string "6"))) + (set_attr "type" "arith")]) + +(define_split + [(set (match_operand:HI 0 "arith_reg_operand" "") + (ashift:HI (match_operand:HI 1 "arith_reg_operand" "") + (match_operand:HI 2 "const_int_operand" "n"))) + (clobber (reg:SI 18))] + "" + [(use (reg:SI 0))] + " +{ + gen_shifty_hi_op (ASHIFT, operands); + DONE; +}") + ; ; arithmetic shift right ; @@ -843,6 +880,15 @@ "shar %0" [(set_attr "type" "arith")]) +(define_insn "ashrhi3_k" + [(set (match_operand:HI 0 "arith_reg_operand" "=r") + (ashiftrt:HI (match_operand:HI 1 "arith_reg_operand" "0") + (match_operand:HI 2 "const_int_operand" "M"))) + (clobber (reg:SI 18))] + "INTVAL (operands[2]) == 1" + "shar %0" + [(set_attr "type" "arith")]) + ;; ??? This should be a define expand. (define_insn "ashrsi2_16" @@ -919,6 +965,22 @@ && ! CONST_OK_FOR_M (INTVAL (operands[2]))" "shlr%O2 %0") +(define_insn "lshrhi3_m" + [(set (match_operand:HI 0 "arith_reg_operand" "=r") + (lshiftrt:HI (match_operand:HI 1 "arith_reg_operand" "0") + (match_operand:HI 2 "const_int_operand" "M"))) + (clobber (reg:SI 18))] + "CONST_OK_FOR_M (INTVAL (operands[2]))" + "shlr %0") + +(define_insn "lshrhi3_k" + [(set (match_operand:HI 0 "arith_reg_operand" "=r") + (lshiftrt:HI (match_operand:HI 1 "arith_reg_operand" "0") + (match_operand:HI 2 "const_int_operand" "K")))] + "CONST_OK_FOR_K (INTVAL (operands[2])) + && ! CONST_OK_FOR_M (INTVAL (operands[2]))" + "shlr%O2 %0") + (define_insn "lshrsi3_n" [(set (match_operand:SI 0 "arith_reg_operand" "=r") (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand" "0") @@ -968,6 +1030,35 @@ FAIL; }") +(define_insn "lshrhi3" + [(set (match_operand:HI 0 "arith_reg_operand" "=r") + (lshiftrt:HI (match_operand:HI 1 "arith_reg_operand" "0") + (match_operand:HI 2 "const_int_operand" "n"))) + (clobber (reg:SI 18))] + "" + "#" +;; ??? length attribute is sometimes six instead of four. + [(set (attr "length") + (cond [(eq (symbol_ref "shift_insns_rtx (insn)") (const_int 1)) + (const_string "2") + (eq (symbol_ref "shift_insns_rtx (insn)") (const_int 2)) + (const_string "4")] + (const_string "6"))) + (set_attr "type" "arith")]) + +(define_split + [(set (match_operand:HI 0 "arith_reg_operand" "") + (lshiftrt:HI (match_operand:HI 1 "arith_reg_operand" "") + (match_operand:HI 2 "const_int_operand" "n"))) + (clobber (reg:SI 18))] + "" + [(use (reg:SI 0))] + " +{ + gen_shifty_hi_op (LSHIFTRT, operands); + DONE; +}") + ;; ??? This should be a define expand. (define_insn "ashldi3_k" @@ -1027,6 +1118,193 @@ "" "{ if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 1) FAIL; } ") + +;; combined left/right shift + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "const_int_operand" "n")) + (match_operand:SI 3 "const_int_operand" "n")))] + "(unsigned)INTVAL (operands[2]) < 32" + [(use (reg:SI 0))] + "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL; + DONE;") + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "const_int_operand" "n")) + (match_operand:SI 3 "const_int_operand" "n"))) + (clobber (reg:SI 18))] + "(unsigned)INTVAL (operands[2]) < 32" + [(use (reg:SI 0))] + "if (gen_shl_and (operands[0], operands[2], operands[3], operands[1])) FAIL; + DONE;") + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 2 "const_int_operand" "n")) + (match_operand:SI 3 "const_int_operand" "n"))) + (clobber (reg:SI 18))] + "shl_and_kind (operands[2], operands[3], 0) == 1" + "#" + [(set (attr "length") + (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2)) + (const_string "4") + (eq (symbol_ref "shl_and_length (insn)") (const_int 3)) + (const_string "6") + (eq (symbol_ref "shl_and_length (insn)") (const_int 4)) + (const_string "8") + (eq (symbol_ref "shl_and_length (insn)") (const_int 5)) + (const_string "10") + (eq (symbol_ref "shl_and_length (insn)") (const_int 6)) + (const_string "12") + (eq (symbol_ref "shl_and_length (insn)") (const_int 7)) + (const_string "14") + (eq (symbol_ref "shl_and_length (insn)") (const_int 8)) + (const_string "16")] + (const_string "18"))) + (set_attr "type" "arith")]) + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=z") + (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 2 "const_int_operand" "n")) + (match_operand:SI 3 "const_int_operand" "n"))) + (clobber (reg:SI 18))] + "shl_and_kind (operands[2], operands[3], 0) == 2" + "#" + [(set (attr "length") + (cond [(eq (symbol_ref "shl_and_length (insn)") (const_int 2)) + (const_string "4") + (eq (symbol_ref "shl_and_length (insn)") (const_int 3)) + (const_string "6") + (eq (symbol_ref "shl_and_length (insn)") (const_int 4)) + (const_string "8")] + (const_string "10"))) + (set_attr "type" "arith")]) + +;; shift left / and combination with a scratch register: The combine pass +;; does not accept the individual instructions, even though they are +;; cheap. But it needs a precise description so that it is usable after +;; reload. +(define_insn "and_shl_scratch" + [(set (match_operand:SI 0 "register_operand" "=r,&r") + (lshiftrt:SI (ashift:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0") + (match_operand:SI 2 "const_int_operand" "N,n")) + (match_operand:SI 3 "" "0,r")) + (match_operand:SI 4 "const_int_operand" "n,n")) + (match_operand:SI 5 "const_int_operand" "n,n"))) + (clobber (reg:SI 18))] + "" + "#" + [(set (attr "length") + (cond [(eq (symbol_ref "shl_and_scr_length (insn)") (const_int 2)) + (const_string "4") + (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 3)) + (const_string "6") + (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 4)) + (const_string "6") + (eq (symbol_ref "shl_and_scr_length (insn)") (const_int 5)) + (const_string "10")] + (const_string "12"))) + (set_attr "type" "arith")]) + +(define_split + [(set (match_operand:SI 0 "register_operand" "=r,&r") + (lshiftrt:SI (ashift:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0") + (match_operand:SI 2 "const_int_operand" "N,n")) + (match_operand:SI 3 "register_operand" "0,r")) + (match_operand:SI 4 "const_int_operand" "n,n")) + (match_operand:SI 5 "const_int_operand" "n,n"))) + (clobber (reg:SI 18))] + "" + [(use (reg:SI 0))] + " +{ + rtx and_source = operands[1]; + + if (INTVAL (operands[2])) + { + gen_shifty_op (LSHIFTRT, operands); + and_source = operands[3]; + } + emit_insn (gen_andsi3 (operands[0], operands[0], and_source)); + operands[2] = operands[4]; + gen_shifty_op (ASHIFT, operands); + if (INTVAL (operands[5])) + { + operands[2] = operands[5]; + gen_shifty_op (LSHIFTRT, operands); + } + DONE; +}") + +;; signed left/right shift combination. +(define_split + [(set (match_operand:SI 0 "register_operand" "=r") + (sign_extract:SI (ashift:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "const_int_operand" "n")) + (match_operand:SI 3 "const_int_operand" "n") + (const_int 0))) + (clobber (reg:SI 18))] + "" + [(use (reg:SI 0))] + "if (gen_shl_sext (operands[0], operands[2], operands[3], operands[1])) FAIL; + DONE;") + +(define_insn "shl_sext_ext" + [(set (match_operand:SI 0 "register_operand" "=r") + (sign_extract:SI (ashift:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 2 "const_int_operand" "n")) + (match_operand:SI 3 "const_int_operand" "n") + (const_int 0))) + (clobber (reg:SI 18))] + "shl_sext_kind (operands[2], operands[3], 0) <= 5" + "#" + [(set (attr "length") + (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 1)) + (const_string "2") + (eq (symbol_ref "shl_sext_length (insn)") (const_int 2)) + (const_string "4") + (eq (symbol_ref "shl_sext_length (insn)") (const_int 3)) + (const_string "6") + (eq (symbol_ref "shl_sext_length (insn)") (const_int 4)) + (const_string "8") + (eq (symbol_ref "shl_sext_length (insn)") (const_int 5)) + (const_string "10") + (eq (symbol_ref "shl_sext_length (insn)") (const_int 6)) + (const_string "12") + (eq (symbol_ref "shl_sext_length (insn)") (const_int 7)) + (const_string "14") + (eq (symbol_ref "shl_sext_length (insn)") (const_int 8)) + (const_string "16")] + (const_string "18"))) + (set_attr "type" "arith")]) + +(define_insn "shl_sext_sub" + [(set (match_operand:SI 0 "register_operand" "=z") + (sign_extract:SI (ashift:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 2 "const_int_operand" "n")) + (match_operand:SI 3 "const_int_operand" "n") + (const_int 0))) + (clobber (reg:SI 18))] + "(shl_sext_kind (operands[2], operands[3], 0) & ~1) == 6" + "#" + [(set (attr "length") + (cond [(eq (symbol_ref "shl_sext_length (insn)") (const_int 3)) + (const_string "6") + (eq (symbol_ref "shl_sext_length (insn)") (const_int 4)) + (const_string "8") + (eq (symbol_ref "shl_sext_length (insn)") (const_int 5)) + (const_string "10") + (eq (symbol_ref "shl_sext_length (insn)") (const_int 6)) + (const_string "12")] + (const_string "14"))) + (set_attr "type" "arith")]) + ;; ------------------------------------------------------------------------- ;; Unary arithmetic |