Hi Guys,

  I am going to apply the patch below to the RX backend to add support
  for generating MIN and MAX instructions for HI and QI modes.

Cheers
  Nick

gcc/ChangeLog
2011-09-28  Nick Clifton  <ni...@redhat.com>

        * config/rx/predicates.md (rx_minmax_operand): New predicate.
        Accepts immediates and a restricted subset of MEMs.
        * config/rx/rx.md (int_modes): New iterator.
        (smaxsi3, sminsi3): Delete and replace with...
        (smax<int_mode>3, smin<int_mode>3): New patterns.
        (umax<>3_u, umax<>3_ur, umax<>3, umin<>3): New patterns.

Index: gcc/config/rx/predicates.md
===================================================================
--- gcc/config/rx/predicates.md (revision 179307)
+++ gcc/config/rx/predicates.md (working copy)
@@ -72,6 +72,16 @@
        (match_operand 0 "rx_restricted_mem_operand"))
 )
 
+;; Check that the operand is suitable as the source operand
+;; for a min/max instruction.  This is the same as
+;; rx_source_operand except that CONST_INTs are allowed but
+;; REGs and SUBREGs are not.
+
+(define_predicate "rx_minmaxex_operand"
+  (ior (match_operand 0 "immediate_operand")
+       (match_operand 0 "rx_restricted_mem_operand"))
+)
+
 ;; Return true if OP is a store multiple operation.  This looks like:
 ;;
 ;;   [(set (SP) (MINUS (SP) (INT)))
Index: gcc/config/rx/rx.md
===================================================================
--- gcc/config/rx/rx.md (revision 179307)
+++ gcc/config/rx/rx.md (working copy)
@@ -22,6 +22,9 @@
 ;; This code iterator is used for sign- and zero- extensions.
 (define_mode_iterator small_int_modes [(HI "") (QI "")])
 
+;; This code iterator is used for max and min operations.
+(define_mode_iterator int_modes [(SI "") (HI "") (QI "")])
+
 ;; We do not handle DFmode here because it is either
 ;; the same as SFmode, or if -m64bit-doubles is active
 ;; then all operations on doubles have to be handled by
@@ -1160,28 +1163,109 @@
    (set_attr "timings" "22,44")]
 )
 
-(define_insn "smaxsi3"
-  [(set (match_operand:SI          0 "register_operand" "=r,r,r,r,r,r")
-       (smax:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
-                (match_operand:SI 2 "rx_source_operand"
-                                  "r,Sint08,Sint16,Sint24,i,Q")))]
+(define_insn "smax<int_modes:mode>3"
+  [(set (match_operand:int_modes                 0 "register_operand" 
"=r,r,r,r,r,r")
+       (smax:int_modes (match_operand:int_modes 1 "register_operand" 
"%0,0,0,0,0,0")
+                       (match_operand:int_modes 2 "rx_source_operand"
+                                                
"r,Sint08,Sint16,Sint24,i,Q")))]
   ""
   "max\t%Q2, %0"
   [(set_attr "length" "3,4,5,6,7,6")
    (set_attr "timings" "11,11,11,11,11,33")]
 )
 
-(define_insn "sminsi3"
-  [(set (match_operand:SI          0 "register_operand" "=r,r,r,r,r,r")
-       (smin:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
-                (match_operand:SI 2 "rx_source_operand"
-                                  "r,Sint08,Sint16,Sint24,i,Q")))]
+(define_insn "smin<int_modes:mode>3"
+  [(set (match_operand:int_modes                 0 "register_operand" 
"=r,r,r,r,r,r")
+       (smin:int_modes (match_operand:int_modes 1 "register_operand" 
"%0,0,0,0,0,0")
+                (match_operand:int_modes        2 "rx_source_operand"
+                                                
"r,Sint08,Sint16,Sint24,i,Q")))]
   ""
   "min\t%Q2, %0"
   [(set_attr "length"  "3,4,5,6,7,6")
    (set_attr "timings" "11,11,11,11,11,33")]
 )
 
+(define_insn "umax<small_int_modes:mode>3_u"
+  [(set (match_operand:SI          0 "register_operand" "=r,r,r,r,r,r")
+       (smax:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")
+                (zero_extend:SI (match_operand:small_int_modes 2 
"rx_minmaxex_operand"
+                                                               
"r,Sint08,Sint16,Sint24,i,Q"))))]
+  ""
+  "max\t%R2, %0"
+  [(set_attr "length"  "3,4,5,6,7,6")
+   (set_attr "timings" "11,11,11,11,11,33")]
+)
+
+(define_insn "umin<small_int_modes:mode>3_ur"
+  [(set (match_operand:SI          0 "register_operand" "=r,r,r,r,r,r")
+       (smin:SI (zero_extend:SI (match_operand:small_int_modes 2 
"rx_minmaxex_operand"
+                                                               
"r,Sint08,Sint16,Sint24,i,Q"))
+                (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")))]
+  ""
+  "min\t%R2, %0"
+  [(set_attr "length"  "3,4,5,6,7,6")
+   (set_attr "timings" "11,11,11,11,11,33")]
+)
+
+(define_insn "umax<small_int_modes:mode>3_ur"
+  [(set (match_operand:SI          0 "register_operand" "=r,r,r,r,r,r")
+       (smax:SI (zero_extend:SI (match_operand:small_int_modes 2 
"rx_minmaxex_operand"
+                                                               
"r,Sint08,Sint16,Sint24,i,Q"))
+                (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0")))]
+  ""
+  "max\t%R2, %0"
+  [(set_attr "length"  "3,4,5,6,7,6")
+   (set_attr "timings" "11,11,11,11,11,33")]
+)
+
+(define_expand "umax<small_int_modes:mode>3"
+  [(set (match_dup 4)
+       (zero_extend:SI (match_operand:small_int_modes 1 "register_operand" 
"%0,0,0,0,0,0")))
+   (set (match_dup 3)
+       (smax:SI (match_dup 4)
+                (match_operand:small_int_modes 2 "rx_source_operand"
+                                               "r,Sint08,Sint16,Sint24,i,Q")))
+   (set (match_operand:small_int_modes          0 "register_operand" 
"=r,r,r,r,r,r")
+       (match_dup 6))
+   ]
+  ""
+  "operands[3] = gen_reg_rtx (SImode);
+   operands[4] = gen_reg_rtx (SImode);
+   operands[5] = gen_reg_rtx (SImode);
+   operands[6] = gen_rtx_SUBREG (GET_MODE (operands[0]), operands[3],
+     TARGET_BIG_ENDIAN_DATA ? (GET_MODE (operands[0]) == HImode ? 2 : 3) : 0);
+   if (GET_CODE (operands[2]) != CONST_INT)
+     {
+       emit_move_insn (operands[5], gen_rtx_ZERO_EXTEND (SImode, operands[2]));
+       operands[2] = operands[5];
+     }
+  "
+)
+
+(define_expand "umin<small_int_modes:mode>3"
+  [(set (match_dup 4)
+       (zero_extend:SI (match_operand:small_int_modes 1 "register_operand" 
"%0,0,0,0,0,0")))
+   (set (match_dup 3)
+       (smin:SI (match_dup 4)
+                (match_operand:small_int_modes 2 "rx_source_operand"
+                                               "r,Sint08,Sint16,Sint24,i,Q")))
+   (set (match_operand:small_int_modes          0 "register_operand" 
"=r,r,r,r,r,r")
+       (match_dup 6))
+   ]
+  ""
+  "operands[3] = gen_reg_rtx (SImode);
+   operands[4] = gen_reg_rtx (SImode);
+   operands[5] = gen_reg_rtx (SImode);
+   operands[6] = gen_rtx_SUBREG (GET_MODE (operands[0]), operands[3],
+     TARGET_BIG_ENDIAN_DATA ? (GET_MODE (operands[0]) == HImode ? 2 : 3) : 0);
+   if (GET_CODE (operands[2]) != CONST_INT)
+     {
+       emit_move_insn (operands[5], gen_rtx_ZERO_EXTEND (SImode, operands[2]));
+       operands[2] = operands[5];
+     }
+   "
+)
+
 (define_insn "mulsi3"
   [(set (match_operand:SI          0 "register_operand" "=r,r,r,r,r,r,r,r,r")
         (mult:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0,0,r,r")

Reply via email to