On Sat, Mar 19, 2016 at 6:15 PM, Pierre Moreau <pierre.mor...@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.mor...@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.mor...@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@lists.freedesktop.org >> > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev