Sujet : Re: Cray style vectors
De : tr.17687 (at) *nospam* z991.linuxsc.com (Tim Rentsch)
Groupes : comp.archDate : 13. Mar 2024, 04:23:32
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <8634surf0r.fsf@linuxsc.com>
References : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
User-Agent : Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
EricP <
ThatWouldBeTelling@thevillage.com> writes:
Anton Ertl wrote:
>
Terje Mathisen <terje.mathisen@tmsw.no> writes:
>
Tim Rentsch wrote:
>
Terje Mathisen <terje.mathisen@tmsw.no> writes:
>
If I really had to write a 64x64->128 MUL, with no widening MUL or
MULH which returns the high half, then I would punt and do it using
32-bit parts (all variables are u64): [...]
>
I wrote some code along the same lines. A difference is you
are considering unsigned multiplication, and I am considering
signed multiplication.
>
Signed mul is just a special case of unsigned mul, right?
>
I.e. in case of a signed widening mul, you'd first extract the
signs, convert the inputs to unsigned, then do the unsigned
widening mul, before finally resotirng the sign as the XOR of the
input signs?
>
In Gforth we use:
>
DCell mmul (Cell a, Cell b) /* signed multiply, mixed precision */
{
DCell res;
>
res = UD2D(ummul (a, b));
if (a < 0)
res.hi -= b;
if (b < 0)
res.hi -= a;
return res;
}
>
I have this technique from Andrew Haley. It relies on twos-complement
representation.
>
Yeah, that's what Alpha does with UMULH.
I'm still trying to figure out why it works.
It works because a sign bit works like a value bit
with a weight of -2**(N-1), where N is the width of
the memory holding the signed value. So instead
of subtracting 2**(N-1) * b, assuming a is negative,
we have instead added 2**(N-1) * b, so we need to
subtract 2 * 2**(N-1) * b, or 2**N * b, which means
subtracting b from the high order word of the result.
And of course similarly for when b is negative.
(Note that the above holds for two's complement, but
not for ones' complement or signed magnitude.)