nvc0/ir: add support for emitting partial min/max ops for int64
authorIlia Mirkin <imirkin@alum.mit.edu>
Sat, 4 Feb 2017 15:55:03 +0000 (10:55 -0500)
committerIlia Mirkin <imirkin@alum.mit.edu>
Thu, 9 Feb 2017 17:57:48 +0000 (12:57 -0500)
These operations allow you to compute min/max on arbitrary-width
integers, 32 bits at a time.

Note that the low/med ops implicitly set the condition code, and the
med/high ops implicitly consume it.

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir.h
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp

index bedbdcc4cd2bbe353cd54a2282903236c6a036df..56e028790cd330f1c2084f98a2c96a229803e366 100644 (file)
@@ -251,6 +251,10 @@ enum operation
 #define NV50_IR_SUBOP_VOTE_ANY 1
 #define NV50_IR_SUBOP_VOTE_UNI 2
 
+#define NV50_IR_SUBOP_MINMAX_LOW  1
+#define NV50_IR_SUBOP_MINMAX_MED  2
+#define NV50_IR_SUBOP_MINMAX_HIGH 3
+
 enum DataType
 {
    TYPE_NONE,
index 123ec5cc00951dbaf24030f2427ca2c66e4c94e0..4f2d817763c646c6faf9a9338d934fdcc602e9b9 100644 (file)
@@ -993,6 +993,9 @@ CodeEmitterGK110::emitMINMAX(const Instruction *i)
    if (i->dType == TYPE_S32)
       code[1] |= 1 << 19;
    code[1] |= (i->op == OP_MIN) ? 0x1c00 : 0x3c00; // [!]pt
+   code[1] |= i->subOp << 14;
+   if (i->flagsDef >= 0)
+      code[1] |= i->subOp << 18;
 
    FTZ_(2f);
    ABS_(31, 0);
index f3ebd2b0be8f7b52a54d0300ea130d251cf537e1..21b9ac42c73495b9e9ffbdde110c1e767c69dc94 100644 (file)
@@ -1867,6 +1867,7 @@ CodeEmitterGM107::emitIMNMX()
 
    emitField(0x30, 1, isSignedType(insn->dType));
    emitCC   (0x2f);
+   emitField(0x2b, 2, insn->subOp);
    emitField(0x2a, 1, insn->op == OP_MAX);
    emitPRED (0x27);
    emitGPR  (0x08, insn->src(0));
index a58335dd8f337b5eb855818d421433c9696c0ca2..b64ac61bf488978ccce1e0796034dc1954aa121a 100644 (file)
@@ -1011,13 +1011,18 @@ CodeEmitterNVC0::emitMINMAX(const Instruction *i)
    if (i->ftz)
       op |= 1 << 5;
    else
-   if (!isFloatType(i->dType))
+   if (!isFloatType(i->dType)) {
       op |= isSignedType(i->dType) ? 0x23 : 0x03;
+      op |= i->subOp << 6;
+   }
    if (i->dType == TYPE_F64)
       op |= 0x01;
 
    emitForm_A(i, op);
    emitNegAbs12(i);
+
+   if (i->flagsDef >= 0)
+      code[1] |= 1 << 16;
 }
 
 void