diff options
author | dj <dj@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-31 02:32:08 +0000 |
---|---|---|
committer | dj <dj@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-31 02:32:08 +0000 |
commit | bbcffae89d5907a05150153b62a554fac3d99d13 (patch) | |
tree | 5086d1d41cbf5a74bb5649d040be9a8309736065 /gcc/config/rx | |
parent | 9631b129ee947613f09a8e4ce3c979f5a6cdfb76 (diff) | |
download | gcc-bbcffae89d5907a05150153b62a554fac3d99d13.tar.gz |
* config/rx/predicates.md (rx_constshift_operand): New.
* config/rx/rx.md (zs_cond): New.
(cbranchsi4): Remove mode.
(*cbranchsi4_<code>): Likewise.
(*tstbranchsi4_<code>): New.
(*tstbranchsi4r_<code>): New.
(*tstbranchsi4m_eq): New.
(*tstbranchsi4m_ne): New.
(cbranchsf4): Remove mode.
(*cbranchsf4_<code>): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@162731 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/rx')
-rw-r--r-- | gcc/config/rx/predicates.md | 7 | ||||
-rw-r--r-- | gcc/config/rx/rx.md | 116 |
2 files changed, 114 insertions, 9 deletions
diff --git a/gcc/config/rx/predicates.md b/gcc/config/rx/predicates.md index 94e5f5630c2..d8def87d6e8 100644 --- a/gcc/config/rx/predicates.md +++ b/gcc/config/rx/predicates.md @@ -45,6 +45,13 @@ } ) +(define_predicate "rx_constshift_operand" + (match_code "const_int") + { + return IN_RANGE (INTVAL (op), 0, 31); + } +) + ;; Check that the operand is suitable as the source operand ;; for a logic or arithmeitc instruction. Registers, integers ;; and a restricted subset of memory addresses are allowed. diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md index aeba85ffe39..0ad53637596 100644 --- a/gcc/config/rx/rx.md +++ b/gcc/config/rx/rx.md @@ -24,6 +24,9 @@ (define_code_iterator most_cond [eq ne gt ge lt le gtu geu ltu leu unordered ordered ]) +;; Likewise, but only the ones that use Z or S. +(define_code_iterator zs_cond [eq ne gtu geu ltu leu ]) + ;; This code iterator is used for sign- and zero- extensions. (define_mode_iterator small_int_modes [(HI "") (QI "")]) @@ -157,9 +160,9 @@ (define_expand "cbranchsi4" [(set (pc) - (if_then_else (match_operator:SI 0 "comparison_operator" - [(match_operand:SI 1 "register_operand") - (match_operand:SI 2 "rx_source_operand")]) + (if_then_else (match_operator 0 "comparison_operator" + [(match_operand:SI 1 "register_operand") + (match_operand:SI 2 "rx_source_operand")]) (label_ref (match_operand 3 "")) (pc))) ] @@ -169,7 +172,7 @@ (define_insn_and_split "*cbranchsi4_<code>" [(set (pc) - (if_then_else (most_cond:SI (match_operand:SI 0 "register_operand" "r") + (if_then_else (most_cond (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "rx_source_operand" "riQ")) (label_ref (match_operand 2 "" "")) (pc))) @@ -189,11 +192,106 @@ " ) +;; ----------------------------------------------------------------------------- +;; These two are the canonical TST/branch insns. However, GCC +;; generates a wide variety of tst-like patterns, we catch those +;; below. +(define_insn_and_split "*tstbranchsi4_<code>" + [(set (pc) + (if_then_else (zs_cond (and:SI (match_operand:SI 0 "register_operand" "r") + (match_operand:SI 1 "rx_source_operand" "riQ")) + (const_int 0)) + (label_ref (match_operand 2 "" "")) + (pc))) + ] + "" + "#" + "reload_completed" + [(const_int 0)] + " + emit_insn (gen_tstsi (operands[0], operands[1])); + + emit_jump_insn (gen_conditional_branch (operands[2], + gen_rtx_fmt_ee (<zs_cond:CODE>, CCmode, + gen_rtx_REG (CCmode, CC_REG), const0_rtx))); + " +) + +;; Inverse of above +(define_insn_and_split "*tstbranchsi4r_<code>" + [(set (pc) + (if_then_else (zs_cond (and:SI (match_operand:SI 0 "register_operand" "r") + (match_operand:SI 1 "rx_source_operand" "riQ")) + (const_int 0)) + (pc) + (label_ref (match_operand 2 "" "")))) + ] + "" + "#" + "reload_completed" + [(const_int 0)] + " + emit_insn (gen_tstsi (operands[0], operands[1])); + + emit_jump_insn (gen_conditional_branch (operands[2], + gen_rtx_fmt_ee (reverse_condition (<zs_cond:CODE>), CCmode, + gen_rtx_REG (CCmode, CC_REG), const0_rtx))); + " +) + +;; Various other ways that GCC codes "var & const" + +(define_insn_and_split "*tstbranchsi4m_eq" + [(set (pc) + (if_then_else (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r") + (match_operand 1 "rx_constshift_operand" "i") + (match_operand 2 "rx_constshift_operand" "i")) + (const_int 0)) + (label_ref (match_operand 3 "" "")) + (pc))) + ] + "" + "#" + "" + [(set (pc) + (if_then_else (eq (and:SI (match_dup 0) + (match_dup 4)) + (const_int 0)) + (label_ref (match_dup 3)) + (pc))) + ] + "operands[4] = GEN_INT (((1 << INTVAL (operands[1]))-1) << INTVAL (operands[2]));" +) + +(define_insn_and_split "*tstbranchsi4m_ne" + [(set (pc) + (if_then_else (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r") + (match_operand 1 "rx_constshift_operand" "i") + (match_operand 2 "rx_constshift_operand" "i")) + (const_int 0)) + (label_ref (match_operand 3 "" "")) + (pc))) + ] + "" + "#" + "" + [(set (pc) + (if_then_else (ne (and:SI (match_dup 0) + (match_dup 4)) + (const_int 0)) + (label_ref (match_dup 3)) + (pc))) + ] + "operands[4] = GEN_INT (((1 << INTVAL (operands[1]))-1) << INTVAL (operands[2]));" +) + +;; ----------------------------------------------------------------------------- + (define_expand "cbranchsf4" [(set (pc) - (if_then_else (match_operator:SF 0 "comparison_operator" - [(match_operand:SF 1 "register_operand") - (match_operand:SF 2 "rx_source_operand")]) + (if_then_else (match_operator 0 "comparison_operator" + [(match_operand:SF 1 "register_operand") + (match_operand:SF 2 "rx_source_operand")]) (label_ref (match_operand 3 "")) (pc))) ] @@ -203,8 +301,8 @@ (define_insn_and_split "*cbranchsf4_<code>" [(set (pc) - (if_then_else (most_cond:SF (match_operand:SF 0 "register_operand" "r") - (match_operand:SF 1 "rx_source_operand" "rFiQ")) + (if_then_else (most_cond (match_operand:SF 0 "register_operand" "r") + (match_operand:SF 1 "rx_source_operand" "rFiQ")) (label_ref (match_operand 2 "" "")) (pc))) ] |