predicates.md (rx_constshift_operand): New.
authorDJ Delorie <dj@redhat.com>
Sat, 31 Jul 2010 02:32:08 +0000 (22:32 -0400)
committerDJ Delorie <dj@gcc.gnu.org>
Sat, 31 Jul 2010 02:32:08 +0000 (22:32 -0400)
* 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.

From-SVN: r162731

gcc/ChangeLog
gcc/config/rx/predicates.md
gcc/config/rx/rx.md

index 582ad92..b417d4b 100644 (file)
@@ -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
index 94e5f56..d8def87 100644 (file)
   }
 )
 
+(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.
index aeba85f..0ad5363 100644 (file)
@@ -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 "")])
 
 
 (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)))
    ]
 
 (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)))
   "
 )
 
+;; -----------------------------------------------------------------------------
+;; 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)))
    ]
 
 (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)))
    ]