On Fri, Sep 27, 2019 at 12:30:50AM +0200, Jakub Jelinek wrote:
> On Thu, Sep 26, 2019 at 05:17:40PM -0500, Segher Boessenkool wrote:
> > On Wed, Sep 25, 2019 at 10:06:13PM -0600, Jeff Law wrote:
> > > (insn 14 13 16 2 (parallel [
> > >             (set (reg:SI 132)
> > >                 (plus:SI (mult:SI (zero_extend:DI (reg/v:SI 115 [ sec ]))
> > >                         (zero_extend:DI (reg:SI 124)))
> > >                     (reg:SI 130)))
> > >             (set (reg:SI 133 [+4 ])
> > >                 (plus:SI (truncate:SI (lshiftrt:DI (plus:DI (mult:DI 
> > > (zero_extend:DI (reg/v:SI 115 [ sec ]))
> > >                                     (zero_extend:DI (reg:SI 124)))
> > >                                 (zero_extend:DI (reg:SI 130)))
> > >                             (const_int 32 [0x20])))
> > >                     (reg:SI 131 [+4 ])))
> > >         ]) "j.c":10:54 60 {umlal}
> > >      (expr_list:REG_DEAD (reg:SI 131 [+4 ])
> > >         (expr_list:REG_DEAD (reg:SI 130)
> > >             (expr_list:REG_DEAD (reg:SI 124)
> > >                 (expr_list:REG_DEAD (reg/v:SI 115 [ sec ])
> > >                     (nil))))))
> > 
> > This is not a correct pattern for umlal (it should have a carry from the
> > low half of the addition to the high half).
> 
> Are you sure?
> "The UMLAL instruction interprets the values from Rn and Rm as unsigned
> integers.  It multiplies these integers, and adds the 64-bit result to the
> 64-bit unsigned integer contained in RdHi and RdLo."

Yes.  It adds two 64-bit numbers.  That is not the same as adding the
top and bottom 32-bit halfs of that separately.

> Appart from the bug I've provided untested fix in the PR, the above pattern
> seems to do what the documentation says, the low 32 bits are
> (unsigned int) (Rn*Rm+RdLo), and the whole result for unsigned int
> Rn, Rm, RdHi and RdLo is
> (unsigned long long)Rn*Rm+((unsigned long long)RdHi<<32)+RdLo
> and the upper 32 bits of that are IMHO equivalent to
> (unsigned) (((unsigned long long)Rn*Rm+RdLo)>>32)+RdHi

The upper half of the result should be one bigger if the addition of the
low half carries.


Segher

Reply via email to