summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp21
1 files changed, 15 insertions, 6 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
index 70f3c3f69ff..e2c3b8ef14d 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
@@ -1808,6 +1808,9 @@ uses64bitAddress(const Instruction *ldst)
void
CodeEmitterGK110::emitATOM(const Instruction *i)
{
+ const bool hasDst = i->defExists(0);
+ const bool exch = i->subOp == NV50_IR_SUBOP_ATOM_EXCH;
+
code[0] = 0x00000002;
if (i->subOp == NV50_IR_SUBOP_ATOM_CAS)
code[1] = 0x77800000;
@@ -1836,15 +1839,21 @@ CodeEmitterGK110::emitATOM(const Instruction *i)
/* TODO: cas: flip bits if $r255 is used */
srcId(i->src(1), 23);
- if (i->defExists(0))
+ if (hasDst) {
defId(i->def(0), 2);
- else
+ } else
+ if (!exch) {
code[0] |= 255 << 2;
+ }
- const int32_t offset = SDATA(i->src(0)).offset;
- assert(offset < 0x80000 && offset >= -0x80000);
- code[0] |= (offset & 1) << 31;
- code[1] |= (offset & 0xffffe) >> 1;
+ if (hasDst || !exch) {
+ const int32_t offset = SDATA(i->src(0)).offset;
+ assert(offset < 0x80000 && offset >= -0x80000);
+ code[0] |= (offset & 1) << 31;
+ code[1] |= (offset & 0xffffe) >> 1;
+ } else {
+ srcAddr32(i->src(0), 31);
+ }
if (i->getIndirect(0, 0)) {
srcId(i->getIndirect(0, 0), 10);