nvc0/ir: fix atomic compare-and-swap arguments

Teach the emitter that the two registers are sequential, and drop the
second arg entirely, in favor of a double-wide first argument.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
This commit is contained in:
Ilia Mirkin 2016-01-10 21:47:04 -05:00
parent 7b9a77b905
commit df043f0764
3 changed files with 8 additions and 5 deletions

View file

@ -2021,8 +2021,10 @@ CodeEmitterNVC0::emitATOM(const Instruction *i)
code[0] |= 63 << 20;
}
if (i->subOp == NV50_IR_SUBOP_ATOM_CAS)
srcId(i->src(2), 32 + 17);
if (i->subOp == NV50_IR_SUBOP_ATOM_CAS) {
assert(i->src(1).getSize() == 2 * typeSizeof(i->sType));
code[1] |= (SDATA(i->src(1)).id + 1) << 17;
}
}
void

View file

@ -2435,13 +2435,13 @@ Converter::handleATOM(Value *dst0[4], DataType ty, uint16_t subOp)
else
sym = makeSym(TGSI_FILE_BUFFER, r, -1, c, 0);
insn = mkOp2(OP_ATOM, ty, dst, sym, fetchSrc(2, c));
if (subOp == NV50_IR_SUBOP_ATOM_CAS)
insn->setSrc(2, fetchSrc(3, 0));
if (tgsi.getSrc(1).getFile() != TGSI_FILE_IMMEDIATE)
insn->setIndirect(0, 0, off);
if (tgsi.getSrc(0).isIndirect(0))
insn->setIndirect(0, 1, fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, 0));
insn->subOp = subOp;
if (subOp == NV50_IR_SUBOP_ATOM_CAS)
insn->setSrc(2, fetchSrc(3, 0));
}
for (int c = 0; c < 4; ++c)
if (dst0[c])

View file

@ -1086,7 +1086,7 @@ NVC0LoweringPass::handleCasExch(Instruction *cas, bool needCctl)
cctl->setPredicate(cas->cc, cas->getPredicate());
}
if (cas->defExists(0) && cas->subOp == NV50_IR_SUBOP_ATOM_CAS) {
if (cas->subOp == NV50_IR_SUBOP_ATOM_CAS) {
// CAS is crazy. It's 2nd source is a double reg, and the 3rd source
// should be set to the high part of the double reg or bad things will
// happen elsewhere in the universe.
@ -1096,6 +1096,7 @@ NVC0LoweringPass::handleCasExch(Instruction *cas, bool needCctl)
bld.setPosition(cas, false);
bld.mkOp2(OP_MERGE, TYPE_U64, dreg, cas->getSrc(1), cas->getSrc(2));
cas->setSrc(1, dreg);
cas->setSrc(2, dreg);
}
return true;