summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSamuel Pitoiset <[email protected]>2016-04-20 19:47:37 +0200
committerSamuel Pitoiset <[email protected]>2016-04-20 22:55:33 +0200
commit17a37c78fc16505f717a44aa22551285d1cd8c9e (patch)
tree830ec9c1a881970b144d0f3a4b86a07ac0a07f0c /src
parent3caf2e89aa1711e80db80d2056e0a44663d9c7d2 (diff)
gk110/ir: do not overwrite def value with zero for EXCH ops
This is only valid for other atomic operations (including CAS). This fixes an invalid opcode error from dmesg. While we are it, make sure to initialize global addr to 0 for other atomic operations. Signed-off-by: Samuel Pitoiset <[email protected]> Reviewed-by: Ilia Mirkin <[email protected]> Cc: "11.1 11.2" <[email protected]>
Diffstat (limited to 'src')
-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);