diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config/rx/predicates.md | 7 | ||||
-rw-r--r-- | gcc/config/rx/rx.md | 116 |
3 files changed, 127 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 582ad92..b417d4b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2010-07-30 DJ Delorie <dj@redhat.com> + + * 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. + 2010-07-30 Bernd Schmidt <bernds@codesourcery.com> * rtlanal.c (simplify_subreg_regno): Don't treat diff --git a/gcc/config/rx/predicates.md b/gcc/config/rx/predicates.md index 94e5f56..d8def87 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 aeba85f..0ad5363 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))) ] |