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);
+ }
}
}
// 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;
}
i->src(0).getFile() != FILE_GPR ||
i->src(1).getFile() != FILE_GPR ||
i->src(2).getFile() != FILE_GPR ||
- i->getDef(0)->reg.data.id != i->getSrc(2)->reg.data.id ||
- !isFloatType(i->dType))
+ i->getDef(0)->reg.data.id != i->getSrc(2)->reg.data.id)
break;
if (i->getDef(0)->reg.data.id >= 64 ||
i->getSrc(0)->reg.data.id >= 64)
break;
+ if (i->flagsSrc >= 0 && i->getSrc(i->flagsSrc)->reg.data.id != 0)
+ break;
+
if (i->getPredicate())
break;
// Short encoding only possible if they're all GPRs, no need to
// affect them otherwise.
if (insn->flagsDef < 0 &&
- isFloatType(insn->dType) &&
insn->src(0).getFile() == FILE_GPR &&
insn->src(1).getFile() == FILE_GPR &&
insn->src(2).getFile() == FILE_GPR)