summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Rusin <zack@tungstengraphics.com>2007-10-18 08:12:48 -0400
committerZack Rusin <zack@tungstengraphics.com>2007-10-24 11:21:04 -0400
commite9a623d6a69718e3a9cc46dbb54cb4e7bd79f09c (patch)
treeb9b8a165f211eb76a12e797d65342290cbecf635
parent3ae767dd073e8c24fc159cb86f89e61ea7a0e85f (diff)
implement min and max
-rw-r--r--src/mesa/pipe/llvm/instructions.cpp102
-rw-r--r--src/mesa/pipe/llvm/instructions.h2
-rw-r--r--src/mesa/pipe/llvm/llvmtgsi.cpp8
3 files changed, 110 insertions, 2 deletions
diff --git a/src/mesa/pipe/llvm/instructions.cpp b/src/mesa/pipe/llvm/instructions.cpp
index d43a617d35..2dd1d1861c 100644
--- a/src/mesa/pipe/llvm/instructions.cpp
+++ b/src/mesa/pipe/llvm/instructions.cpp
@@ -413,3 +413,105 @@ llvm::Value * Instructions::lg2(llvm::Value *in)
callFLog(z), callFLog(w)), const_vec);
}
+llvm::Value * Instructions::min(llvm::Value *in1, llvm::Value *in2)
+{
+ ExtractElementInst *x1 = new ExtractElementInst(in1, unsigned(0),
+ name("x1"),
+ m_block);
+ ExtractElementInst *y1 = new ExtractElementInst(in1, unsigned(1),
+ name("y1"),
+ m_block);
+ ExtractElementInst *z1 = new ExtractElementInst(in1, unsigned(2),
+ name("z1"),
+ m_block);
+ ExtractElementInst *w1 = new ExtractElementInst(in1, unsigned(3),
+ name("w1"),
+ m_block);
+
+ ExtractElementInst *x2 = new ExtractElementInst(in2, unsigned(0),
+ name("x2"),
+ m_block);
+ ExtractElementInst *y2 = new ExtractElementInst(in2, unsigned(1),
+ name("y2"),
+ m_block);
+ ExtractElementInst *z2 = new ExtractElementInst(in2, unsigned(2),
+ name("z2"),
+ m_block);
+ ExtractElementInst *w2 = new ExtractElementInst(in2, unsigned(3),
+ name("w2"),
+ m_block);
+
+ FCmpInst *xcmp = new FCmpInst(FCmpInst::FCMP_OLT, x1, x2,
+ name("xcmp"), m_block);
+ SelectInst *selx = new SelectInst(xcmp, x1, x2,
+ name("selx"), m_block);
+
+ FCmpInst *ycmp = new FCmpInst(FCmpInst::FCMP_OLT, y1, y2,
+ name("ycmp"), m_block);
+ SelectInst *sely = new SelectInst(ycmp, y1, y2,
+ name("sely"), m_block);
+
+ FCmpInst *zcmp = new FCmpInst(FCmpInst::FCMP_OLT, z1, z2,
+ name("zcmp"), m_block);
+ SelectInst *selz = new SelectInst(zcmp, z1, z2,
+ name("selz"), m_block);
+
+ FCmpInst *wcmp = new FCmpInst(FCmpInst::FCMP_OLT, w1, w2,
+ name("wcmp"), m_block);
+ SelectInst *selw = new SelectInst(wcmp, w1, w2,
+ name("selw"), m_block);
+
+ return vectorFromVals(selx, sely, selz, selw);
+}
+
+llvm::Value * Instructions::max(llvm::Value *in1, llvm::Value *in2)
+{
+ ExtractElementInst *x1 = new ExtractElementInst(in1, unsigned(0),
+ name("x1"),
+ m_block);
+ ExtractElementInst *y1 = new ExtractElementInst(in1, unsigned(1),
+ name("y1"),
+ m_block);
+ ExtractElementInst *z1 = new ExtractElementInst(in1, unsigned(2),
+ name("z1"),
+ m_block);
+ ExtractElementInst *w1 = new ExtractElementInst(in1, unsigned(3),
+ name("w1"),
+ m_block);
+
+ ExtractElementInst *x2 = new ExtractElementInst(in2, unsigned(0),
+ name("x2"),
+ m_block);
+ ExtractElementInst *y2 = new ExtractElementInst(in2, unsigned(1),
+ name("y2"),
+ m_block);
+ ExtractElementInst *z2 = new ExtractElementInst(in2, unsigned(2),
+ name("z2"),
+ m_block);
+ ExtractElementInst *w2 = new ExtractElementInst(in2, unsigned(3),
+ name("w2"),
+ m_block);
+
+ FCmpInst *xcmp = new FCmpInst(FCmpInst::FCMP_OGT, x1, x2,
+ name("xcmp"), m_block);
+ SelectInst *selx = new SelectInst(xcmp, x1, x2,
+ name("selx"), m_block);
+
+ FCmpInst *ycmp = new FCmpInst(FCmpInst::FCMP_OGT, y1, y2,
+ name("ycmp"), m_block);
+ SelectInst *sely = new SelectInst(ycmp, y1, y2,
+ name("sely"), m_block);
+
+ FCmpInst *zcmp = new FCmpInst(FCmpInst::FCMP_OGT, z1, z2,
+ name("zcmp"), m_block);
+ SelectInst *selz = new SelectInst(zcmp, z1, z2,
+ name("selz"), m_block);
+
+ FCmpInst *wcmp = new FCmpInst(FCmpInst::FCMP_OGT, w1, w2,
+ name("wcmp"), m_block);
+ SelectInst *selw = new SelectInst(wcmp, w1, w2,
+ name("selw"), m_block);
+
+ return vectorFromVals(selx, sely, selz, selw);
+}
+
diff --git a/src/mesa/pipe/llvm/instructions.h b/src/mesa/pipe/llvm/instructions.h
index e6ad47ebd2..dd1e76728a 100644
--- a/src/mesa/pipe/llvm/instructions.h
+++ b/src/mesa/pipe/llvm/instructions.h
@@ -26,6 +26,8 @@ public:
llvm::Value *lg2(llvm::Value *in);
llvm::Value *madd(llvm::Value *in1, llvm::Value *in2,
llvm::Value *in2);
+ llvm::Value *min(llvm::Value *in1, llvm::Value *in2);
+ llvm::Value *max(llvm::Value *in1, llvm::Value *in2);
llvm::Value *mul(llvm::Value *in1, llvm::Value *in2);
llvm::Value *pow(llvm::Value *in1, llvm::Value *in2);
llvm::Value *rcp(llvm::Value *in);
diff --git a/src/mesa/pipe/llvm/llvmtgsi.cpp b/src/mesa/pipe/llvm/llvmtgsi.cpp
index b2f6d17e96..9b4a5f024e 100644
--- a/src/mesa/pipe/llvm/llvmtgsi.cpp
+++ b/src/mesa/pipe/llvm/llvmtgsi.cpp
@@ -213,9 +213,13 @@ translate_instruction(llvm::Module *module,
out = instr->dst(inputs[0], inputs[1]);
}
break;
- case TGSI_OPCODE_MIN:
+ case TGSI_OPCODE_MIN: {
+ out = instr->min(inputs[0], inputs[1]);
+ }
break;
- case TGSI_OPCODE_MAX:
+ case TGSI_OPCODE_MAX: {
+ out = instr->max(inputs[0], inputs[1]);
+ }
break;
case TGSI_OPCODE_SLT:
break;