diff options
Diffstat (limited to 'src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp')
-rw-r--r-- | src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp index 216e119af63..00be37769af 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nv50.cpp @@ -1190,29 +1190,45 @@ CodeEmitterNV50::emitDMUL(const Instruction *i) void CodeEmitterNV50::emitIMAD(const Instruction *i) { + int mode; code[0] = 0x60000000; - if (isSignedType(i->sType)) - code[1] = i->saturate ? 0x40000000 : 0x20000000; - else - code[1] = 0x00000000; - - int neg1 = i->src(0).mod.neg() ^ i->src(1).mod.neg(); - int neg2 = i->src(2).mod.neg(); - assert(!(neg1 & neg2)); - code[1] |= neg1 << 27; - code[1] |= neg2 << 26; + assert(!i->src(0).mod && !i->src(1).mod && !i->src(2).mod); + if (!isSignedType(i->sType)) + mode = 0; + else if (i->saturate) + mode = 2; + else + mode = 1; - if (i->src(1).getFile() == FILE_IMMEDIATE) + if (i->src(1).getFile() == FILE_IMMEDIATE) { + code[1] = 0; emitForm_IMM(i); - else + code[0] |= (mode & 1) << 8 | (mode & 2) << 14; + if (i->flagsSrc >= 0) { + assert(!(code[0] & 0x10400000)); + assert(SDATA(i->src(i->flagsSrc)).id == 0); + code[0] |= 0x10400000; + } + } else + if (i->encSize == 4) { + emitForm_MUL(i); + code[0] |= (mode & 1) << 8 | (mode & 2) << 14; + if (i->flagsSrc >= 0) { + assert(!(code[0] & 0x10400000)); + assert(SDATA(i->src(i->flagsSrc)).id == 0); + code[0] |= 0x10400000; + } + } else { + code[1] = mode << 29; emitForm_MAD(i); - if (i->flagsSrc >= 0) { - // add with carry from $cX - assert(!(code[1] & 0x0c000000) && !i->getPredicate()); - code[1] |= 0xc << 24; - srcId(i->src(i->flagsSrc), 32 + 12); + if (i->flagsSrc >= 0) { + // add with carry from $cX + assert(!(code[1] & 0x0c000000) && !i->getPredicate()); + code[1] |= 0xc << 24; + srcId(i->src(i->flagsSrc), 32 + 12); + } } } @@ -2054,8 +2070,9 @@ CodeEmitterNV50::getMinEncodingSize(const Instruction *i) const // check constraints on short MAD if (info.srcNr >= 2 && i->srcExists(2)) { - if (!i->defExists(0) || !isFloatType(i->dType) || - i->def(0).rep()->reg.data.id != i->src(2).rep()->reg.data.id) + if (!i->defExists(0) || + (i->flagsSrc >= 0 && SDATA(i->src(i->flagsSrc)).id > 0) || + DDATA(i->def(0)).id != SDATA(i->src(2)).id) return 8; } |