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")