diff options
author | Samuel Pitoiset <[email protected]> | 2016-02-28 20:44:47 +0100 |
---|---|---|
committer | Samuel Pitoiset <[email protected]> | 2016-02-28 23:58:11 +0100 |
commit | 07ed003faf3199a3e95852e7a34763aeaf76503d (patch) | |
tree | 1b6cf92b018ab198418f933d124dd4ba17eaaf15 | |
parent | b3efa0a59e02e20ccd9ed51c6e503d020f619043 (diff) |
nv50/ir: emit VOTE instruction
Changes from v2:
- add missing NOT modifier for GK110/GM107
Signed-off-by: Samuel Pitoiset <[email protected]>
Reviewed-by: Ilia Mirkin <[email protected]>
6 files changed, 83 insertions, 0 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir.h b/src/gallium/drivers/nouveau/codegen/nv50_ir.h index 97ebed455b6..7b0eb2f95b8 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir.h @@ -161,6 +161,7 @@ enum operation OP_VSEL, OP_CCTL, // cache control OP_SHFL, // warp shuffle + OP_VOTE, OP_LAST }; @@ -244,6 +245,9 @@ enum operation #define NV50_IR_SUBOP_V2(d,a,b) (((d) << 10) | ((b) << 5) | (a) | 0x4000) #define NV50_IR_SUBOP_V4(d,a,b) (((d) << 10) | ((b) << 5) | (a) | 0x8000) #define NV50_IR_SUBOP_Vn(n) ((n) >> 14) +#define NV50_IR_SUBOP_VOTE_ALL 0 +#define NV50_IR_SUBOP_VOTE_ANY 1 +#define NV50_IR_SUBOP_VOTE_UNI 2 enum DataType { 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 90c6a6107b5..b6b3ec7b948 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp @@ -128,6 +128,8 @@ private: void emitFlow(const Instruction *); + void emitVOTE(const Instruction *); + inline void defId(const ValueDef&, const int pos); inline void srcId(const ValueRef&, const int pos); inline void srcId(const ValueRef *, const int pos); @@ -1371,6 +1373,24 @@ CodeEmitterGK110::emitFlow(const Instruction *i) } void +CodeEmitterGK110::emitVOTE(const Instruction *i) +{ + assert(i->src(0).getFile() == FILE_PREDICATE && + i->def(1).getFile() == FILE_PREDICATE); + + code[0] = 0x00000002; + code[1] = 0x86c00000 | (i->subOp << 19); + + emitPredicate(i); + + defId(i->def(0), 2); + defId(i->def(1), 48); + if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT)) + code[0] |= 1 << 45; + srcId(i->src(0), 42); +} + +void CodeEmitterGK110::emitAFETCH(const Instruction *i) { uint32_t offset = i->src(0).get()->reg.data.offset & 0x7ff; @@ -2080,6 +2100,9 @@ CodeEmitterGK110::emitInstruction(Instruction *insn) case OP_CCTL: emitCCTL(insn); break; + case OP_VOTE: + emitVOTE(insn); + break; case OP_PHI: case OP_UNION: case OP_CONSTRAINT: 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 93c40d15e46..a383c53fcd3 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp @@ -195,6 +195,8 @@ private: void emitOUT(); void emitMEMBAR(); + + void emitVOTE(); }; /******************************************************************************* @@ -2653,6 +2655,30 @@ CodeEmitterGM107::emitMEMBAR() emitField(0x08, 2, insn->subOp >> 2); } +void +CodeEmitterGM107::emitVOTE() +{ + int subOp; + + assert(insn->src(0).getFile() == FILE_PREDICATE && + insn->def(1).getFile() == FILE_PREDICATE); + + switch (insn->subOp) { + case NV50_IR_SUBOP_VOTE_ANY: subOp = 1; break; + default: + assert(insn->subOp == NV50_IR_SUBOP_VOTE_ALL); + subOp = 0; + break; + } + + emitInsn (0x50d80000); + emitField(0x30, 2, subOp); + emitGPR (0x00, insn->def(0)); + emitPRED (0x2d, insn->def(1)); + emitField(0x2a, 1, insn->src(0).mod == Modifier(NV50_IR_MOD_NOT)); + emitPRED (0x27, insn->src(0)); +} + /******************************************************************************* * assembler front-end ******************************************************************************/ @@ -2955,6 +2981,9 @@ CodeEmitterGM107::emitInstruction(Instruction *i) case OP_MEMBAR: emitMEMBAR(); break; + case OP_VOTE: + emitVOTE(); + break; default: assert(!"invalid opcode"); emitNOP(); diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp index 0068da5cbb7..7bd7c732c49 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp @@ -142,6 +142,8 @@ private: void emitPIXLD(const Instruction *); + void emitVOTE(const Instruction *); + inline void defId(const ValueDef&, const int pos); inline void defId(const Instruction *, int d, const int pos); inline void srcId(const ValueRef&, const int pos); @@ -2334,6 +2336,24 @@ CodeEmitterNVC0::emitPIXLD(const Instruction *i) code[1] |= 0x00e00000; } +void +CodeEmitterNVC0::emitVOTE(const Instruction *i) +{ + assert(i->src(0).getFile() == FILE_PREDICATE && + i->def(1).getFile() == FILE_PREDICATE); + + code[0] = 0x00000004 | (i->subOp << 5); + code[1] = 0x48000000; + + emitPredicate(i); + + defId(i->def(0), 14); + defId(i->def(1), 32 + 22); + if (i->src(0).mod == Modifier(NV50_IR_MOD_NOT)) + code[0] |= 1 << 23; + srcId(i->src(0), 20); +} + bool CodeEmitterNVC0::emitInstruction(Instruction *insn) { @@ -2604,6 +2624,9 @@ CodeEmitterNVC0::emitInstruction(Instruction *insn) case OP_PIXLD: emitPIXLD(insn); break; + case OP_VOTE: + emitVOTE(insn); + break; case OP_PHI: case OP_UNION: case OP_CONSTRAINT: diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp index 85f77047c5c..cfa85ec123c 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_print.cpp @@ -190,6 +190,7 @@ const char *operationStr[OP_LAST + 1] = "vsel", "cctl", "shfl", + "vote", "(invalid)" }; diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp index 89d3a08937f..160e36fd7b1 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_target.cpp @@ -55,6 +55,7 @@ const uint8_t Target::operationSrcNr[] = 2, 2, 2, 2, 3, 2, // VADD, VAVG, VMIN, VMAX, VSAD, VSET, 2, 2, 2, 1, // VSHR, VSHL, VSEL, CCTL 3, // SHFL + 1, // VOTE 0 }; @@ -129,6 +130,8 @@ const OpClass Target::operationClass[] = OPCLASS_VECTOR, OPCLASS_CONTROL, // SHFL OPCLASS_OTHER, + // VOTE + OPCLASS_OTHER, OPCLASS_PSEUDO // LAST }; |