summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
index 5ed2ad4ba93..5bd0fa0a075 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
@@ -180,6 +180,7 @@ private:
void emitIPA();
void emitATOM();
void emitATOMS();
+ void emitRED();
void emitCCTL();
void emitPIXLD();
@@ -2496,6 +2497,29 @@ CodeEmitterGM107::emitATOMS()
}
void
+CodeEmitterGM107::emitRED()
+{
+ unsigned dType;
+
+ switch (insn->dType) {
+ case TYPE_U32: dType = 0; break;
+ case TYPE_S32: dType = 1; break;
+ case TYPE_U64: dType = 2; break;
+ case TYPE_F32: dType = 3; break;
+ case TYPE_B128: dType = 4; break;
+ case TYPE_S64: dType = 5; break;
+ default: assert(!"unexpected dType"); dType = 0; break;
+ }
+
+ emitInsn (0xebf80000);
+ emitField(0x30, 1, insn->src(0).getIndirect(0)->getSize() == 8);
+ emitField(0x17, 3, insn->subOp);
+ emitField(0x14, 3, dType);
+ emitADDR (0x08, 0x1c, 20, 0, insn->src(0));
+ emitGPR (0x00, insn->src(1));
+}
+
+void
CodeEmitterGM107::emitCCTL()
{
unsigned width;
@@ -3237,7 +3261,10 @@ CodeEmitterGM107::emitInstruction(Instruction *i)
if (insn->src(0).getFile() == FILE_MEMORY_SHARED)
emitATOMS();
else
- emitATOM();
+ if (!insn->defExists(0) && insn->subOp < NV50_IR_SUBOP_ATOM_CAS)
+ emitRED();
+ else
+ emitATOM();
break;
case OP_CCTL:
emitCCTL();