gm107/ir: add emission for SUREDx
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Fri, 24 Jun 2016 20:35:59 +0000 (22:35 +0200)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Wed, 20 Jul 2016 09:11:26 +0000 (11:11 +0200)
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp

index 7d77ca3be42a4e044b0a2474b1d34af28fe6b6d1..791273faa0b639628ad1b30827fc831511c575f8 100644 (file)
@@ -205,6 +205,7 @@ private:
    void emitSUHandle(const int s);
    void emitSUSTx();
    void emitSULDx();
+   void emitSUREDx();
 };
 
 /*******************************************************************************
@@ -2913,6 +2914,51 @@ CodeEmitterGM107::emitSULDx()
 
    emitSUHandle(1);
 }
+
+void
+CodeEmitterGM107::emitSUREDx()
+{
+   const TexInstruction *insn = this->insn->asTex();
+   uint8_t type = 0, subOp;
+
+   if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS)
+      emitInsn(0xeac00000);
+   else
+      emitInsn(0xea600000);
+
+   if (insn->op == OP_SUREDB)
+      emitField(0x34, 1, 1);
+   emitSUTarget();
+
+   // destination type
+   switch (insn->dType) {
+   case TYPE_S32: type = 1; break;
+   case TYPE_U64: type = 2; break;
+   case TYPE_F32: type = 3; break;
+   case TYPE_S64: type = 5; break;
+   default:
+      assert(insn->dType == TYPE_U32);
+      break;
+   }
+
+   // atomic operation
+   if (insn->subOp == NV50_IR_SUBOP_ATOM_CAS) {
+      subOp = 0;
+   } else if (insn->subOp == NV50_IR_SUBOP_ATOM_EXCH) {
+      subOp = 8;
+   } else {
+      subOp = insn->subOp;
+   }
+
+   emitField(0x24, 3, type);
+   emitField(0x1d, 4, subOp);
+   emitGPR  (0x14, insn->src(1));
+   emitGPR  (0x08, insn->src(0));
+   emitGPR  (0x00, insn->def(0));
+
+   emitSUHandle(2);
+}
+
 /*******************************************************************************
  * assembler front-end
  ******************************************************************************/
@@ -3235,6 +3281,10 @@ CodeEmitterGM107::emitInstruction(Instruction *i)
    case OP_SULDP:
       emitSULDx();
       break;
+   case OP_SUREDB:
+   case OP_SUREDP:
+      emitSUREDx();
+      break;
    default:
       assert(!"invalid opcode");
       emitNOP();