implement min and max
authorZack Rusin <zack@tungstengraphics.com>
Thu, 18 Oct 2007 12:12:48 +0000 (08:12 -0400)
committerZack Rusin <zack@tungstengraphics.com>
Wed, 24 Oct 2007 15:21:04 +0000 (11:21 -0400)
src/mesa/pipe/llvm/instructions.cpp
src/mesa/pipe/llvm/instructions.h
src/mesa/pipe/llvm/llvmtgsi.cpp

index d43a617d35e12bebcdad92675c78fbbfc1399f54..2dd1d1861cb6bda00f2b1bf426004b1febd2e813 100644 (file)
@@ -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);
+}
+
index e6ad47ebd28471ec38525cd2cfd55fa38b4458f9..dd1e76728abac91355ccec0ecb5480ef98ac9bb6 100644 (file)
@@ -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);
index b2f6d17e96632b05ea01d774b56ee47289f2fc83..9b4a5f024ed030c0b22bceefdcbcb2221951c1e8 100644 (file)
@@ -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;