On Mon, Jul 11, 2011 at 12:38:34PM +0200, Georg-Johann Lay wrote:
> How do I write a pre-reload combine + pre-reload split correctly?
> I'd like to avoid clobber reg.
> 
> Thanks much for any hint.

The move patterns are always kind of funny, particularly during register
allocation.

Lets see given your pattern is:

(define_insn_and_split "*mulsqihi3.const"
  [(set (match_operand:HI 0 "register_operand" "=&r")
        (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
                 (match_operand:HI 2 "u8_operand" "n")))]
  "AVR_HAVE_MUL
   && !reload_completed
   && !reload_in_progress"
  { gcc_unreachable(); }
  "&& 1"
  [(set (match_dup 3)
        (match_dup 2))
   ; *mulsu
   (set (match_dup 0)
        (mult:HI (sign_extend:HI (match_dup 1))
                 (zero_extend:HI (match_dup 3))))]
  {
    operands[3] = gen_reg_rtx (QImode);
  })

I would probably rewrite it as:

(define_insn_and_split "*mulsqihi3.const"
  [(set (match_operand:HI 0 "register_operand" "=&r")
        (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
                 (match_operand:HI 2 "u8_operand" "n")))]
  "AVR_HAVE_MUL
   && !reload_completed
   && !reload_in_progress"
  { gcc_unreachable(); }
  "&& 1"
  [(set (match_dup 3)
        (unspec:QI [(match_dup 2)] WRAPPER))
   ; *mulsu
   (set (match_dup 0)
        (mult:HI (sign_extend:HI (match_dup 1))
                 (zero_extend:HI (match_dup 3))))]
  {
    operands[3] = gen_reg_rtx (QImode);
  })

(define_insn "*wrapper"
  [(set (match_operand:QI 0 "register_operand" "=&r")
        (unspec:QI [(match_operand:QI 1 "u8_operand" "n")] WRAPPER))]
  "AVR_HAVE_MUL"
  "...")

That way you are using the unspec to make the move not look like a generic
move.

The other way to do it, would be to split it to another pattern that combines
the move and the HI multiply, which you then split after reload.  Something
like:

(define_insn_and_split "*mulsqihi3_const"
  [(set (match_operand:HI 0 "register_operand" "=&r")
        (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "a"))
                 (match_operand:HI 2 "u8_operand" "n")))]
  "AVR_HAVE_MUL
   && !reload_completed
   && !reload_in_progress"
  { gcc_unreachable(); }
  "&& 1"
  [(parallel [(set (match_dup 3)
                   (match_dup 2))
              ; *mulsu
              (set (match_dup 0)
                   (mult:HI (sign_extend:HI (match_dup 1))
                            (zero_extend:HI (match_dup 3))))])]
  {
    operands[3] = gen_reg_rtx (QImode);
  })

(define_insn_and_split "*mulsqihi3_const2"
  [(set (match_operand:QI 0 "register_operand" "r")
        (match_operand:QI 1 "u8_operand" "n"))
   (set (match_operand:HI 2 "register_operand" "r")
        (mult:HI (sign_extend:HI (match_operand:QI 3 "register_operand" "a"))
                 (zero_extend:HI (match_dup 0))))]
  "AVR_HAV_MUL"
  "#"
  "&& reload_completed"
  [(set (match_dup 0)
        (match_dup 1))
   (set (match_dup 2)
        (mult:HI (sign_extend:HI (match_dup 3))
                 (zero_extend:HI (match_dup 0))))]
   {})

-- 
Michael Meissner, IBM
5 Technology Place Drive, M/S 2757, Westford, MA 01886-3141, USA
meiss...@linux.vnet.ibm.com     fax +1 (978) 399-6899

Reply via email to