nvc0/ir: fix atomic compare-and-swap arguments
authorIlia Mirkin <imirkin@alum.mit.edu>
Mon, 11 Jan 2016 02:47:04 +0000 (21:47 -0500)
committerIlia Mirkin <imirkin@alum.mit.edu>
Sat, 30 Jan 2016 02:22:48 +0000 (21:22 -0500)
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>
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp

index 0b28047e22bc2b90b69434a1b0d699b51362a536..6cf69e5339fd8a039bbb431b7374fbf5acffe5d7 100644 (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
index 735e2891cf25fa575b63ced0055d0e9ba282a406..947d97be7f10fa819544aff2984acc699701d0ba 100644 (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])
index 0a77dce85c2e1db5709f18ba8b722db1d543c478..e7cb54bc426ec7e78e3a237766cba4cf5f072e8f 100644 (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;