From: Ilia Mirkin Date: Sat, 4 Feb 2017 15:55:03 +0000 (-0500) Subject: nvc0/ir: add support for emitting partial min/max ops for int64 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=eac5099c11c27aa49901846e254c92a4bd1723e2;p=mesa.git nvc0/ir: add support for emitting partial min/max ops for int64 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 --- diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir.h b/src/gallium/drivers/nouveau/codegen/nv50_ir.h index bedbdcc4cd2..56e028790cd 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir.h @@ -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, 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 123ec5cc009..4f2d817763c 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp @@ -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); 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 f3ebd2b0be8..21b9ac42c73 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gm107.cpp @@ -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)); 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 a58335dd8f3..b64ac61bf48 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp @@ -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