summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSamuel Pitoiset <[email protected]>2016-02-05 15:09:07 +0100
committerSamuel Pitoiset <[email protected]>2016-02-21 10:42:29 +0100
commite0371e63df173be38a086a5d816eeaf0e8cbe7eb (patch)
tree6f2127b75f65564b5105ce4f642a93039fb57e03 /src
parent0c930557bf96721ce50ca95b5201be09da905cb8 (diff)
nv50/ir: make OP_SELP a compare instruction
This OP_SELP insn will be used to handle compare and swap subops. Changes from v2: - fix logic for GK110+ Signed-off-by: Samuel Pitoiset <[email protected]> Reviewed-by: Ilia Mirkin <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp12
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp13
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h4
3 files changed, 19 insertions, 10 deletions
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 4bb4e5240e6..8268e08b118 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_gk110.cpp
@@ -112,7 +112,7 @@ private:
void emitSET(const CmpInstruction *);
void emitSLCT(const CmpInstruction *);
- void emitSELP(const Instruction *);
+ void emitSELP(const CmpInstruction *);
void emitTEXBAR(const Instruction *);
void emitTEX(const TexInstruction *);
@@ -433,6 +433,10 @@ CodeEmitterGK110::emitForm_21(const Instruction *i, uint32_t opc2,
srcId(i->src(s), s ? ((s == 2) ? 42 : s1) : 10);
break;
default:
+ if (i->op == OP_SELP) {
+ assert(s == 2 && i->src(s).getFile() == FILE_PREDICATE);
+ srcId(i->src(s), 42);
+ }
// ignore here, can be predicate or flags, but must not be address
break;
}
@@ -1041,11 +1045,11 @@ CodeEmitterGK110::emitSLCT(const CmpInstruction *i)
}
}
-void CodeEmitterGK110::emitSELP(const Instruction *i)
+void CodeEmitterGK110::emitSELP(const CmpInstruction *i)
{
emitForm_21(i, 0x250, 0x050);
- if ((i->cc == CC_NOT_P) ^ (bool)(i->src(2).mod & Modifier(NV50_IR_MOD_NOT)))
+ if ((i->setCond == CC_NOT_P) ^ (bool)(i->src(2).mod & Modifier(NV50_IR_MOD_NOT)))
code[1] |= 1 << 13;
}
@@ -1933,7 +1937,7 @@ CodeEmitterGK110::emitInstruction(Instruction *insn)
emitSET(insn->asCmp());
break;
case OP_SELP:
- emitSELP(insn);
+ emitSELP(insn->asCmp());
break;
case OP_SLCT:
emitSLCT(insn->asCmp());
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 a7c49a24efb..d588d7e8845 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
@@ -120,7 +120,7 @@ private:
void emitSET(const CmpInstruction *);
void emitSLCT(const CmpInstruction *);
- void emitSELP(const Instruction *);
+ void emitSELP(const CmpInstruction *);
void emitTEXBAR(const Instruction *);
void emitTEX(const TexInstruction *);
@@ -398,6 +398,11 @@ CodeEmitterNVC0::emitForm_A(const Instruction *i, uint64_t opc)
srcId(i->src(s), s ? ((s == 2) ? 49 : s1) : 20);
break;
default:
+ if (i->op == OP_SELP) {
+ // OP_SELP is used to implement shared+atomics on Fermi.
+ assert(s == 2 && i->src(s).getFile() == FILE_PREDICATE);
+ srcId(i->src(s), 49);
+ }
// ignore here, can be predicate or flags, but must not be address
break;
}
@@ -1170,11 +1175,11 @@ CodeEmitterNVC0::emitSLCT(const CmpInstruction *i)
code[0] |= 1 << 5;
}
-void CodeEmitterNVC0::emitSELP(const Instruction *i)
+void CodeEmitterNVC0::emitSELP(const CmpInstruction *i)
{
emitForm_A(i, HEX64(20000000, 00000004));
- if (i->cc == CC_NOT_P || i->src(2).mod & Modifier(NV50_IR_MOD_NOT))
+ if (i->setCond == CC_NOT_P || i->src(2).mod & Modifier(NV50_IR_MOD_NOT))
code[1] |= 1 << 20;
}
@@ -2433,7 +2438,7 @@ CodeEmitterNVC0::emitInstruction(Instruction *insn)
emitSET(insn->asCmp());
break;
case OP_SELP:
- emitSELP(insn);
+ emitSELP(insn->asCmp());
break;
case OP_SLCT:
emitSLCT(insn->asCmp());
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h
index e465f24845b..02e6157e65b 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_inlines.h
@@ -281,14 +281,14 @@ Value *TexInstruction::getIndirectS() const
CmpInstruction *Instruction::asCmp()
{
- if (op >= OP_SET_AND && op <= OP_SLCT && op != OP_SELP)
+ if (op >= OP_SET_AND && op <= OP_SLCT)
return static_cast<CmpInstruction *>(this);
return NULL;
}
const CmpInstruction *Instruction::asCmp() const
{
- if (op >= OP_SET_AND && op <= OP_SLCT && op != OP_SELP)
+ if (op >= OP_SET_AND && op <= OP_SLCT)
return static_cast<const CmpInstruction *>(this);
return NULL;
}