diff options
Diffstat (limited to 'src/gallium/drivers/nouveau')
-rw-r--r-- | src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp | 50 |
1 files changed, 50 insertions, 0 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 7d77ca3be42..791273faa0b 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp @@ -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(); |