[Mesa-dev] [PATCH] nv50/ir: Split 64-bit MAD and MUL operations
Ilia Mirkin
imirkin at alum.mit.edu
Sat Mar 19 22:24:28 UTC 2016
On Sat, Mar 19, 2016 at 6:15 PM, Pierre Moreau <pierre.morrow at free.fr> wrote:
> On 06:05 PM - Mar 19 2016, Ilia Mirkin wrote:
>> Not 100% sure, but pretty sure this is wrong. Can you provide the
>> generated sequence of instructions in response to a 64-bit mul and
>> mad?
>
> For the given mul:
>
> mul u64 %r55d %r42d %r52d
>
> the following is generated:
>
> mul u32 { $r0 $c0 } $r0 $r2
> mul (SUBOP:1) u32 $r1 $r1 $r3 $c0
That's not enough though... you need 4 mul's... if you have numbers
(ab) * (cd) where a/b are the high/low of the 64-bit int, that results
in
b*d + (a*d + b * d) * (1 << 32)
See expandIntegerMultiply in there -- it's meant for splitting a
32-bit multiply into 16x16 muls (which is what nv50 can do), but the
same principle applies to splitting 64x64 into 32x32's.
-ilia
>
>
> Whereas for the mad, I need to first find how to tell Nouveau to stop splitting
> each of my mads to mul + add…
>
>>
>> On Sat, Mar 19, 2016 at 5:56 PM, Pierre Moreau <pierre.morrow at free.fr> wrote:
>> > Two 32-bit MAD or MUL operations are generated in place of the original 64-bit
>> > operation. All operands can either be signed or unsigned, but they have to be
>> > integers.
>> >
>> > Signed-off-by: Pierre Moreau <pierre.morrow at free.fr>
>> > ---
>> > src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.cpp | 11 ++++++++++-
>> > 1 file changed, 10 insertions(+), 1 deletion(-)
>> >
>> > diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.cpp
>> > index 84ebfdb..0b37fcf 100644
>> > --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.cpp
>> > +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_build_util.cpp
>> > @@ -586,6 +586,12 @@ BuildUtil::split64BitOpPostRA(Function *fn, Instruction *i,
>> > srcNr = 2;
>> > break;
>> > case OP_SELP: srcNr = 3; break;
>> > + case OP_MAD: /* fallthrough */
>> > + case OP_MUL:
>> > + if (!carry || isFloatType(i->dType) || isFloatType(i->sType))
>> > + return NULL;
>> > + srcNr = (i->op == OP_MAD) ? 3 : 2;
>> > + break;
>> > default:
>> > // TODO when needed
>> > return NULL;
>> > @@ -600,6 +606,9 @@ BuildUtil::split64BitOpPostRA(Function *fn, Instruction *i,
>> >
>> > hi->getDef(0)->reg.data.id++;
>> >
>> > + if (i->op == OP_MAD || i->op == OP_MUL)
>> > + hi->subOp = NV50_IR_SUBOP_MUL_HIGH;
>> > +
>> > for (int s = 0; s < srcNr; ++s) {
>> > if (lo->getSrc(s)->reg.size < 8) {
>> > if (s == 2)
>> > @@ -629,7 +638,7 @@ BuildUtil::split64BitOpPostRA(Function *fn, Instruction *i,
>> > }
>> > }
>> > }
>> > - if (srcNr == 2) {
>> > + if (srcNr >= 2) {
>> > lo->setFlagsDef(1, carry);
>> > hi->setFlagsSrc(hi->srcCount(), carry);
>> > }
>> > --
>> > 2.7.4
>> >
>> > _______________________________________________
>> > mesa-dev mailing list
>> > mesa-dev at lists.freedesktop.org
>> > https://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list