On 3/24/07, Grant Edwards <[email protected]> wrote:
On 2007-03-24, Ralf Hildebrandt <[email protected]> wrote:

>>> r = (uint32_t)u1 * u2;
>>
>> GCC generates the exact same code (as it should).
>
> O.k, then GCC is smart,

Almost.  But that's nothign to do with my quuestion: For the
above code why are u1 and u2 converted to 32-bit values before
being passed to the 16x16=>32 multiply routine?

> but don't expect other compilers to show the same behavior.

I expect any decent compiler to recognize that it only needs to
do a 16x16=>32 multiply, but that's got nothing to do with my
question.



I think the two clr instructions come come from these lines in the machine
description file (gcc/config/msp430/msp430.c):

;; ================== unsigned  hi -> si =============================
(define_expand "umulhisi3"
 [(set (match_operand:SI 0 "nonimmediate_operand_msp430" "")
       (mult:SI (zero_extend:SI (match_operand:HI 1
"nonimmediate_operand_msp430" ""))
                (zero_extend:SI (match_operand:HI 2
"general_operand_msp430" ""))))]
 ""
 "{msp430_umulhisi_guard
(operands); DONE;}")

(define_insn "*umulhisi3_call"
 [(set (reg:SI 14) (mult:SI (zero_extend:SI (reg:HI 10))
                        (zero_extend:SI (reg:HI 12))))
       (clobber (reg:HI 10))
       (clobber (reg:HI 11))
   (clobber (reg:HI 12))
     (clobber (reg:HI 13))]
 "!MSP430_HAS_HWMUL_INTERNAL"
 "clr    r11
   clr    r13
   call    #__umulhisi3"
 [(set_attr "length" "2")
  (set_attr "cc" "clobber")])


I'm not an expert on the GCC internals, but it looks like no one has taken
the time to write a 16 X 16 = 32 bit multiplication yet, and it was faked by
making the umulhisi3 take SI arguments before calling __umulhisi3().  Note
the :zero_extend:SI" in the define_expand block, and the clobber lines in
the define_insn block.

So, GCC recognizes that it can do a 16X16 multiply with 32 bit result and
uses umulhisi3.  The MSP430 port, in turn, forces the inputs to umulhisi3 to
be zero extended to SI arguments, then calls __umulhisi3, which is nothing
more than "br #__mulsi3" (in libgcc.S).

So, the compiler (GCC common code) is smart enough to recognize what you
expect it to, and the MSP430 port generates code that is functional in all
situations, but slower than it could be.  It looks like it would be
straightforward to fix msp430.md and libgcc.S if the two "clr" instructions
are a problem in your case.

Neil

Reply via email to