summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/gallivm/instructions.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/gallivm/instructions.cpp')
-rw-r--r--src/gallium/auxiliary/gallivm/instructions.cpp1193
1 files changed, 0 insertions, 1193 deletions
diff --git a/src/gallium/auxiliary/gallivm/instructions.cpp b/src/gallium/auxiliary/gallivm/instructions.cpp
deleted file mode 100644
index ee8162efce5..00000000000
--- a/src/gallium/auxiliary/gallivm/instructions.cpp
+++ /dev/null
@@ -1,1193 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
- /*
- * Authors:
- * Zack Rusin [email protected]
- */
-#ifdef MESA_LLVM
-
-#include "instructions.h"
-
-#include "storage.h"
-
-#include "util/u_memory.h"
-
-#include <llvm/CallingConv.h>
-#include <llvm/Constants.h>
-#include <llvm/DerivedTypes.h>
-#include <llvm/Function.h>
-#include <llvm/InstrTypes.h>
-#include <llvm/Instructions.h>
-#include <llvm/Attributes.h>
-#include <llvm/Support/MemoryBuffer.h>
-#include <llvm/Bitcode/ReaderWriter.h>
-
-#include <sstream>
-#include <fstream>
-#include <iostream>
-
-using namespace llvm;
-
-#include "gallivm_builtins.cpp"
-
-#if 0
-llvm::Value *arrayFromChannels(std::vector<llvm::Value*> &vals)
-{
- VectorType *vectorType = VectorType::get(Type::FloatTy, 4);
- ArrayType *vectorArray = ArrayType::get(vectorType, 4);
-}
-#endif
-
-static inline std::string createFuncName(int label)
-{
- std::ostringstream stream;
- stream << "function";
- stream << label;
- return stream.str();
-}
-
-Instructions::Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block,
- Storage *storage)
- : m_mod(mod), m_func(func), m_builder(block), m_idx(0),
- m_storage(storage)
-{
- m_floatVecType = VectorType::get(Type::FloatTy, 4);
-
- m_llvmFSqrt = 0;
- m_llvmFAbs = 0;
- m_llvmPow = 0;
- m_llvmFloor = 0;
- m_llvmFlog = 0;
- m_llvmFexp = 0;
- m_llvmLit = 0;
- m_fmtPtr = 0;
-
- MemoryBuffer *buffer = MemoryBuffer::getMemBuffer(
- (const char*)&llvm_builtins_data[0],
- (const char*)&llvm_builtins_data[Elements(llvm_builtins_data)-1]);
- m_mod = ParseBitcodeFile(buffer);
-}
-
-llvm::BasicBlock * Instructions::currentBlock() const
-{
- return m_builder.GetInsertBlock();
-}
-
-llvm::Value * Instructions::abs(llvm::Value *in)
-{
- std::vector<llvm::Value*> vec = extractVector(in);
- Value *xabs = callFAbs(vec[0]);
- Value *yabs = callFAbs(vec[1]);
- Value *zabs = callFAbs(vec[2]);
- Value *wabs = callFAbs(vec[3]);
- return vectorFromVals(xabs, yabs, zabs, wabs);
-}
-
-llvm::Value * Instructions::add(llvm::Value *in1, llvm::Value *in2)
-{
- return m_builder.CreateAdd(in1, in2, name("add"));
-}
-
-llvm::Value * Instructions::arl(llvm::Value *in)
-{
- return floor(in);
-}
-
-void Instructions::beginLoop()
-{
- BasicBlock *begin = BasicBlock::Create(name("loop"), m_func,0);
- BasicBlock *end = BasicBlock::Create(name("endloop"), m_func,0);
-
- m_builder.CreateBr(begin);
- Loop loop;
- loop.begin = begin;
- loop.end = end;
- m_builder.SetInsertPoint(begin);
- m_loopStack.push(loop);
-}
-
-void Instructions::bgnSub(unsigned label)
-{
- llvm::Function *func = findFunction(label);
-
- Function::arg_iterator args = func->arg_begin();
- Value *ptr_INPUT = args++;
- ptr_INPUT->setName("INPUT");
- m_storage->pushArguments(ptr_INPUT);
-
- llvm::BasicBlock *entry = BasicBlock::Create("entry", func, 0);
-
- m_func = func;
- m_builder.SetInsertPoint(entry);
-}
-
-void Instructions::brk()
-{
- assert(!m_loopStack.empty());
- BasicBlock *unr = BasicBlock::Create(name("unreachable"), m_func,0);
- m_builder.CreateBr(m_loopStack.top().end);
- m_builder.SetInsertPoint(unr);
-}
-
-void Instructions::cal(int label, llvm::Value *input)
-{
- std::vector<Value*> params;
- params.push_back(input);
- llvm::Function *func = findFunction(label);
-
- m_builder.CreateCall(func, params.begin(), params.end());
-}
-
-llvm::Value * Instructions::ceil(llvm::Value *in)
-{
- std::vector<llvm::Value*> vec = extractVector(in);
- return vectorFromVals(callCeil(vec[0]), callCeil(vec[1]),
- callCeil(vec[2]), callCeil(vec[3]));
-}
-
-llvm::Value * Instructions::clamp(llvm::Value *in1)
-{
- llvm::Value *zero = constVector(0.0f, 0.0f, 0.0f, 0.0f);
- llvm::Value *one = constVector(1.0f, 1.0f, 1.0f, 1.0f);
- return min( max(zero, in1), one);
-}
-
-llvm::Value * Instructions::cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3)
-{
- llvm::Function *func = m_mod->getFunction("cmp");
- assert(func);
-
- std::vector<Value*> params;
- params.push_back(in1);
- params.push_back(in2);
- params.push_back(in3);
- CallInst *call = m_builder.CreateCall(func, params.begin(), params.end(), name("cmpres"));
- call->setTailCall(false);
- return call;
-}
-
-llvm::Value * Instructions::cnd(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3)
-{
- std::vector<llvm::Value*> vec1 = extractVector(in1);
- std::vector<llvm::Value*> vec2 = extractVector(in2);
- std::vector<llvm::Value*> vec3 = extractVector(in3);
- Constant *half = ConstantFP::get(APFloat(0.5f));
-
- Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], half, name("xcmp"));
- Value *selx = m_builder.CreateSelect(xcmp, vec2[0], vec3[0],
- name("selx"));
-
- Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], half, name("ycmp"));
- Value *sely = m_builder.CreateSelect(ycmp, vec2[1], vec3[1],
- name("sely"));
-
- Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], half, name("zcmp"));
- Value *selz = m_builder.CreateSelect(zcmp, vec2[2], vec3[2],
- name("selz"));
-
- Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], half, name("wcmp"));
- Value *selw = m_builder.CreateSelect(wcmp, vec2[3], vec3[3],
- name("selw"));
-
- return vectorFromVals(selx, sely, selz, selw);
-}
-
-llvm::Value * Instructions::cnd0(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3)
-{
- std::vector<llvm::Value*> vec1 = extractVector(in1);
- std::vector<llvm::Value*> vec2 = extractVector(in2);
- std::vector<llvm::Value*> vec3 = extractVector(in3);
- Constant *zero = Constant::getNullValue(Type::FloatTy);
-
- Value *xcmp = m_builder.CreateFCmpOGE(vec1[0], zero, name("xcmp"));
- Value *selx = m_builder.CreateSelect(xcmp, vec2[0], vec3[0],
- name("selx"));
-
- Value *ycmp = m_builder.CreateFCmpOGE(vec1[1], zero, name("ycmp"));
- Value *sely = m_builder.CreateSelect(ycmp, vec2[1], vec3[1],
- name("sely"));
-
- Value *zcmp = m_builder.CreateFCmpOGE(vec1[2], zero, name("zcmp"));
- Value *selz = m_builder.CreateSelect(zcmp, vec2[2], vec3[2],
- name("selz"));
-
- Value *wcmp = m_builder.CreateFCmpOGE(vec1[3], zero, name("wcmp"));
- Value *selw = m_builder.CreateSelect(wcmp, vec2[3], vec3[3],
- name("selw"));
-
- return vectorFromVals(selx, sely, selz, selw);
-}
-
-llvm::Value * Instructions::cos(llvm::Value *in)
-{
-#if 0
- llvm::Function *func = m_mod->getFunction("vcos");
- assert(func);
-
- CallInst *call = m_builder.CreateCall(func, in, name("cosres"));
- call->setTailCall(false);
- return call;
-#else
- std::vector<llvm::Value*> elems = extractVector(in);
- Function *func = m_mod->getFunction("cosf");
- assert(func);
- CallInst *cos = m_builder.CreateCall(func, elems[0], name("cosres"));
- cos->setCallingConv(CallingConv::C);
- cos->setTailCall(true);
- return vectorFromVals(cos, cos, cos, cos);
-#endif
-}
-
-llvm::Value * Instructions::cross(llvm::Value *in1, llvm::Value *in2)
-{
- Value *x1 = m_builder.CreateExtractElement(in1,
- m_storage->constantInt(0),
- name("x1"));
- Value *y1 = m_builder.CreateExtractElement(in1,
- m_storage->constantInt(1),
- name("y1"));
- Value *z1 = m_builder.CreateExtractElement(in1,
- m_storage->constantInt(2),
- name("z1"));
-
- Value *x2 = m_builder.CreateExtractElement(in2,
- m_storage->constantInt(0),
- name("x2"));
- Value *y2 = m_builder.CreateExtractElement(in2,
- m_storage->constantInt(1),
- name("y2"));
- Value *z2 = m_builder.CreateExtractElement(in2,
- m_storage->constantInt(2),
- name("z2"));
- Value *y1z2 = mul(y1, z2);
- Value *z1y2 = mul(z1, y2);
-
- Value *z1x2 = mul(z1, x2);
- Value *x1z2 = mul(x1, z2);
-
- Value *x1y2 = mul(x1, y2);
- Value *y1x2 = mul(y1, x2);
-
- return vectorFromVals(sub(y1z2, z1y2), sub(z1x2, x1z2), sub(x1y2, y1x2));
-}
-
-llvm::Value * Instructions::ddx(llvm::Value *in)
-{
- // FIXME
- assert(0);
-}
-
-llvm::Value * Instructions::ddy(llvm::Value *in)
-{
- // FIXME
- assert(0);
-}
-
-llvm::Value * Instructions::div(llvm::Value *in1, llvm::Value *in2)
-{
- return m_builder.CreateFDiv(in1, in2, name("div"));
-}
-
-llvm::Value * Instructions::dot2add(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3)
-{
- Value *mulRes = mul(in1, in2);
- Value *x = m_builder.CreateExtractElement(mulRes,
- m_storage->constantInt(0),
- name("extractx"));
- Value *y = m_builder.CreateExtractElement(mulRes,
- m_storage->constantInt(1),
- name("extracty"));
- Value *z = m_builder.CreateExtractElement(in3,
- m_storage->constantInt(2),
- name("extractz"));
- Value *xy = m_builder.CreateAdd(x, y,name("xy"));
- Value *dot2add = m_builder.CreateAdd(xy, z, name("dot2add"));
- return vectorFromVals(dot2add, dot2add, dot2add, dot2add);
-}
-
-llvm::Value * Instructions::dp2(llvm::Value *in1, llvm::Value *in2)
-{
- Value *mulRes = mul(in1, in2);
- Value *x = m_builder.CreateExtractElement(mulRes,
- m_storage->constantInt(0),
- name("extractx"));
- Value *y = m_builder.CreateExtractElement(mulRes,
- m_storage->constantInt(1),
- name("extracty"));
- Value *xy = m_builder.CreateAdd(x, y,name("xy"));
- return vectorFromVals(xy, xy, xy, xy);
-}
-
-llvm::Value * Instructions::dp3(llvm::Value *in1, llvm::Value *in2)
-{
- Value *mulRes = mul(in1, in2);
- Value *x = m_builder.CreateExtractElement(mulRes,
- m_storage->constantInt(0),
- name("extractx"));
- Value *y = m_builder.CreateExtractElement(mulRes,
- m_storage->constantInt(1),
- name("extracty"));
- Value *z = m_builder.CreateExtractElement(mulRes,
- m_storage->constantInt(2),
- name("extractz"));
- Value *xy = m_builder.CreateAdd(x, y,name("xy"));
- Value *dot3 = m_builder.CreateAdd(xy, z, name("dot3"));
- return vectorFromVals(dot3, dot3, dot3, dot3);
-}
-
-llvm::Value * Instructions::dp4(llvm::Value *in1, llvm::Value *in2)
-{
- Value *mulRes = mul(in1, in2);
- std::vector<llvm::Value*> vec = extractVector(mulRes);
- Value *xy = m_builder.CreateAdd(vec[0], vec[1], name("xy"));
- Value *xyz = m_builder.CreateAdd(xy, vec[2], name("xyz"));
- Value *dot4 = m_builder.CreateAdd(xyz, vec[3], name("dot4"));
- return vectorFromVals(dot4, dot4, dot4, dot4);
-}
-
-llvm::Value * Instructions::dph(llvm::Value *in1, llvm::Value *in2)
-{
- Value *mulRes = mul(in1, in2);
- std::vector<llvm::Value*> vec1 = extractVector(mulRes);
- Value *xy = m_builder.CreateAdd(vec1[0], vec1[1], name("xy"));
- Value *xyz = m_builder.CreateAdd(xy, vec1[2], name("xyz"));
- Value *dph = m_builder.CreateAdd(xyz, vec1[3], name("dph"));
- return vectorFromVals(dph, dph, dph, dph);
-}
-
-llvm::Value * Instructions::dst(llvm::Value *in1, llvm::Value *in2)
-{
- Value *y1 = m_builder.CreateExtractElement(in1,
- m_storage->constantInt(1),
- name("y1"));
- Value *z = m_builder.CreateExtractElement(in1,
- m_storage->constantInt(2),
- name("z"));
- Value *y2 = m_builder.CreateExtractElement(in2,
- m_storage->constantInt(1),
- name("y2"));
- Value *w = m_builder.CreateExtractElement(in2,
- m_storage->constantInt(3),
- name("w"));
- Value *ry = m_builder.CreateMul(y1, y2, name("tyuy"));
- return vectorFromVals(ConstantFP::get(APFloat(1.f)),
- ry, z, w);
-}
-
-void Instructions::elseop()
-{
- assert(!m_ifStack.empty());
- BasicBlock *ifend = BasicBlock::Create(name("ifend"), m_func,0);
- m_builder.CreateBr(ifend);
- m_builder.SetInsertPoint(m_ifStack.top());
- currentBlock()->setName(name("ifelse"));
- m_ifStack.pop();
- m_ifStack.push(ifend);
-}
-
-void Instructions::endif()
-{
- assert(!m_ifStack.empty());
- m_builder.CreateBr(m_ifStack.top());
- m_builder.SetInsertPoint(m_ifStack.top());
- m_ifStack.pop();
-}
-
-void Instructions::endLoop()
-{
- assert(!m_loopStack.empty());
- Loop loop = m_loopStack.top();
- m_builder.CreateBr(loop.begin);
- loop.end->moveAfter(currentBlock());
- m_builder.SetInsertPoint(loop.end);
- m_loopStack.pop();
-}
-
-void Instructions::end()
-{
- m_builder.CreateRetVoid();
-}
-
-void Instructions::endSub()
-{
- m_func = 0;
- m_builder.SetInsertPoint(0);
-}
-
-llvm::Value * Instructions::exp(llvm::Value *in)
-{
- std::vector<llvm::Value*> vec = extractVector(in);
- return vectorFromVals(callFExp(vec[0]), callFExp(vec[1]),
- callFExp(vec[2]), callFExp(vec[3]));
-}
-
-llvm::Value * Instructions::ex2(llvm::Value *in)
-{
- llvm::Value *val = callPow(ConstantFP::get(APFloat(2.f)),
- m_builder.CreateExtractElement(
- in, m_storage->constantInt(0),
- name("x1")));
- return vectorFromVals(val, val, val, val);
-}
-
-llvm::Value * Instructions::floor(llvm::Value *in)
-{
- std::vector<llvm::Value*> vec = extractVector(in);
- return vectorFromVals(callFloor(vec[0]), callFloor(vec[1]),
- callFloor(vec[2]), callFloor(vec[3]));
-}
-
-llvm::Value * Instructions::frc(llvm::Value *in)
-{
- llvm::Value *flr = floor(in);
- return sub(in, flr);
-}
-
-void Instructions::ifop(llvm::Value *in)
-{
- BasicBlock *ifthen = BasicBlock::Create(name("ifthen"), m_func,0);
- BasicBlock *ifend = BasicBlock::Create(name("ifthenend"), m_func,0);
-
- //BasicBlock *yblock = new BasicBlock(name("yblock"), m_func,0);
- //BasicBlock *zblock = new BasicBlock(name("zblock"), m_func,0);
- //BasicBlock *wblock = new BasicBlock(name("wblock"), m_func,0);
-
- Constant *float0 = Constant::getNullValue(Type::FloatTy);
-
- Value *x = m_builder.CreateExtractElement(in, m_storage->constantInt(0),
- name("extractx"));
- Value *xcmp = m_builder.CreateFCmpUNE(x, float0, name("xcmp"));
- m_builder.CreateCondBr(xcmp, ifthen, ifend);
- //m_builder.SetInsertPoint(yblock);
-
- m_builder.SetInsertPoint(ifthen);
- m_ifStack.push(ifend);
-}
-
-llvm::Value * Instructions::kil(llvm::Value *in)
-{
- llvm::Function *func = m_mod->getFunction("kil");
- assert(func);
-
- CallInst *call = m_builder.CreateCall(func, in, name("kilpres"));
- call->setTailCall(false);
- return call;
-}
-
-llvm::Value * Instructions::lerp(llvm::Value *in1, llvm::Value *in2,
- llvm::Value *in3)
-{
- llvm::Value *m = mul(in1, in2);
- llvm::Value *vec1 = constVector(1.f, 1.f, 1.f, 1.f);
- llvm::Value *s = sub(vec1, in1);
- return add(m, mul(s, in3));
-}
-
-llvm::Value * Instructions::lg2(llvm::Value *in)
-{
- std::vector<llvm::Value*> vec = extractVector(in);
- llvm::Value *const_vec = constVector(1.442695f, 1.442695f,
- 1.442695f, 1.442695f);
- return mul(vectorFromVals(callFLog(vec[0]), callFLog(vec[1]),
- callFLog(vec[2]), callFLog(vec[3])), const_vec);
-}
-
-llvm::Value * Instructions::lit(llvm::Value *in)
-{
- if (!m_llvmLit) {
- m_llvmLit = m_mod->getFunction("lit");
- }
- CallInst *call = m_builder.CreateCall(m_llvmLit, in, name("litres"));
- call->setCallingConv(CallingConv::C);
- call->setTailCall(false);
- return call;
-}
-
-llvm::Value * Instructions::log(llvm::Value *in)
-{
- std::vector<llvm::Value*> vec = extractVector(in);
- return vectorFromVals(callFLog(vec[0]), callFLog(vec[1]),
- callFLog(vec[2]), callFLog(vec[3]));
-}
-
-llvm::Value * Instructions::madd(llvm::Value *in1, llvm::Value *in2,
- llvm::Value *in3)
-{
- Value *mulRes = mul(in1, in2);
- return add(mulRes, in3);
-}
-
-llvm::Value * Instructions::max(llvm::Value *in1, llvm::Value *in2)
-{
- std::vector<llvm::Value*> vec1 = extractVector(in1);
- std::vector<llvm::Value*> vec2 = extractVector(in2);
-
- Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0],
- name("xcmp"));
- Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0],
- name("selx"));
-
- Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1],
- name("ycmp"));
- Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1],
- name("sely"));
-
- Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2],
- name("zcmp"));
- Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2],
- name("selz"));
-
- Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3],
- name("wcmp"));
- Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3],
- name("selw"));
-
- return vectorFromVals(selx, sely, selz, selw);
-}
-
-llvm::Value * Instructions::min(llvm::Value *in1, llvm::Value *in2)
-{
- std::vector<llvm::Value*> vec1 = extractVector(in1);
- std::vector<llvm::Value*> vec2 = extractVector(in2);
-
- Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp"));
- Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0],
- name("selx"));
-
- Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp"));
- Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1],
- name("sely"));
-
- Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp"));
- Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2],
- name("selz"));
-
- Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp"));
- Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3],
- name("selw"));
-
- return vectorFromVals(selx, sely, selz, selw);
-}
-
-llvm::Value * Instructions::mul(llvm::Value *in1, llvm::Value *in2)
-{
- return m_builder.CreateMul(in1, in2, name("mul"));
-}
-
-llvm::Value * Instructions::neg(llvm::Value *in)
-{
- Value *neg = m_builder.CreateNeg(in, name("neg"));
- return neg;
-}
-
-llvm::Value * Instructions::nrm(llvm::Value *in)
-{
- llvm::Value *v = rsq(in);
- return mul(v, in);
-}
-
-llvm::Value * Instructions::pow(llvm::Value *in1, llvm::Value *in2)
-{
- Value *x1 = m_builder.CreateExtractElement(in1,
- m_storage->constantInt(0),
- name("x1"));
- Value *x2 = m_builder.CreateExtractElement(in2,
- m_storage->constantInt(0),
- name("x2"));
- llvm::Value *val = callPow(x1, x2);
- return vectorFromVals(val, val, val, val);
-}
-
-llvm::Value * Instructions::rcp(llvm::Value *in1)
-{
- Value *x1 = m_builder.CreateExtractElement(in1,
- m_storage->constantInt(0),
- name("x1"));
- Value *res = m_builder.CreateFDiv(ConstantFP::get(APFloat(1.f)),
- x1, name("rcp"));
- return vectorFromVals(res, res, res, res);
-}
-
-llvm::Value * Instructions::rsq(llvm::Value *in1)
-{
- Value *x = m_builder.CreateExtractElement(in1,
- m_storage->constantInt(0),
- name("extractx"));
- Value *abs = callFAbs(x);
- Value *sqrt = callFSqrt(abs);
-
- Value *rsqrt = m_builder.CreateFDiv(ConstantFP::get(APFloat(1.f)),
- sqrt,
- name("rsqrt"));
- return vectorFromVals(rsqrt, rsqrt, rsqrt, rsqrt);
-}
-
-llvm::Value * Instructions::scs(llvm::Value *in)
-{
- llvm::Function *func = m_mod->getFunction("scs");
- assert(func);
-
- CallInst *call = m_builder.CreateCall(func, in, name("scsres"));
- call->setTailCall(false);
- return call;
-}
-
-llvm::Value * Instructions::seq(llvm::Value *in1, llvm::Value *in2)
-{
- Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
- Constant *const0f = Constant::getNullValue(Type::FloatTy);
-
- std::vector<llvm::Value*> vec1 = extractVector(in1);
- std::vector<llvm::Value*> vec2 = extractVector(in2);
-
- Value *xcmp = m_builder.CreateFCmpOEQ(vec1[0], vec2[0], name("xcmp"));
- Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
-
- Value *ycmp = m_builder.CreateFCmpOEQ(vec1[1], vec2[1], name("ycmp"));
- Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
-
- Value *zcmp = m_builder.CreateFCmpOEQ(vec1[2], vec2[2], name("zcmp"));
- Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
-
- Value *wcmp = m_builder.CreateFCmpOEQ(vec1[3], vec2[3], name("wcmp"));
- Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
-
- return vectorFromVals(x, y, z, w);
-}
-
-llvm::Value * Instructions::sfl(llvm::Value *in1, llvm::Value *in2)
-{
- Constant *const0f = Constant::getNullValue(Type::FloatTy);
-
- return vectorFromVals(const0f, const0f, const0f, const0f);
-}
-
-llvm::Value * Instructions::sge(llvm::Value *in1, llvm::Value *in2)
-{
- Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
- Constant *const0f = Constant::getNullValue(Type::FloatTy);
-
- std::vector<llvm::Value*> vec1 = extractVector(in1);
- std::vector<llvm::Value*> vec2 = extractVector(in2);
-
- Value *xcmp = m_builder.CreateFCmpOGE(vec1[0], vec2[0], name("xcmp"));
- Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
-
- Value *ycmp = m_builder.CreateFCmpOGE(vec1[1], vec2[1], name("ycmp"));
- Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
-
- Value *zcmp = m_builder.CreateFCmpOGE(vec1[2], vec2[2], name("zcmp"));
- Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
-
- Value *wcmp = m_builder.CreateFCmpOGE(vec1[3], vec2[3], name("wcmp"));
- Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
-
- return vectorFromVals(x, y, z, w);
-}
-
-llvm::Value * Instructions::sgt(llvm::Value *in1, llvm::Value *in2)
-{
- Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
- Constant *const0f = Constant::getNullValue(Type::FloatTy);
-
- std::vector<llvm::Value*> vec1 = extractVector(in1);
- std::vector<llvm::Value*> vec2 = extractVector(in2);
- Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], name("xcmp"));
- Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
-
- Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], name("ycmp"));
- Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
-
- Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], name("zcmp"));
- Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
-
- Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], name("wcmp"));
- Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
-
- return vectorFromVals(x, y, z, w);
-}
-
-llvm::Value * Instructions::sin(llvm::Value *in)
-{
- llvm::Function *func = m_mod->getFunction("vsin");
- assert(func);
-
- CallInst *call = m_builder.CreateCall(func, in, name("sinres"));
- call->setTailCall(false);
- return call;
-}
-
-llvm::Value * Instructions::sle(llvm::Value *in1, llvm::Value *in2)
-{
- Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
- Constant *const0f = Constant::getNullValue(Type::FloatTy);
-
- std::vector<llvm::Value*> vec1 = extractVector(in1);
- std::vector<llvm::Value*> vec2 = extractVector(in2);
-
- Value *xcmp = m_builder.CreateFCmpOLE(vec1[0], vec2[0], name("xcmp"));
- Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
-
- Value *ycmp = m_builder.CreateFCmpOLE(vec1[1], vec2[1], name("ycmp"));
- Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
-
- Value *zcmp = m_builder.CreateFCmpOLE(vec1[2], vec2[2], name("zcmp"));
- Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
-
- Value *wcmp = m_builder.CreateFCmpOLE(vec1[3], vec2[3], name("wcmp"));
- Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
-
- return vectorFromVals(x, y, z, w);
-}
-
-llvm::Value * Instructions::slt(llvm::Value *in1, llvm::Value *in2)
-{
- Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
- Constant *const0f = Constant::getNullValue(Type::FloatTy);
-
- std::vector<llvm::Value*> vec1 = extractVector(in1);
- std::vector<llvm::Value*> vec2 = extractVector(in2);
-
- Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp"));
- Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
-
- Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp"));
- Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
-
- Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp"));
- Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
-
- Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp"));
- Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
-
- return vectorFromVals(x, y, z, w);
-}
-
-llvm::Value * Instructions::sne(llvm::Value *in1, llvm::Value *in2)
-{
- Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
- Constant *const0f = Constant::getNullValue(Type::FloatTy);
-
- std::vector<llvm::Value*> vec1 = extractVector(in1);
- std::vector<llvm::Value*> vec2 = extractVector(in2);
-
- Value *xcmp = m_builder.CreateFCmpONE(vec1[0], vec2[0], name("xcmp"));
- Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
-
- Value *ycmp = m_builder.CreateFCmpONE(vec1[1], vec2[1], name("ycmp"));
- Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
-
- Value *zcmp = m_builder.CreateFCmpONE(vec1[2], vec2[2], name("zcmp"));
- Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
-
- Value *wcmp = m_builder.CreateFCmpONE(vec1[3], vec2[3], name("wcmp"));
- Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
-
- return vectorFromVals(x, y, z, w);
-}
-
-llvm::Value * Instructions::str(llvm::Value *in1, llvm::Value *in2)
-{
- Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
-
- return vectorFromVals(const1f, const1f, const1f, const1f);
-}
-
-llvm::Value * Instructions::sub(llvm::Value *in1, llvm::Value *in2)
-{
- Value *res = m_builder.CreateSub(in1, in2, name("sub"));
- return res;
-}
-
-llvm::Value * Instructions::trunc(llvm::Value *in)
-{
- std::vector<llvm::Value*> vec = extractVector(in);
- Value *icastx = m_builder.CreateFPToSI(vec[0], IntegerType::get(32),
- name("ftoix"));
- Value *icasty = m_builder.CreateFPToSI(vec[1], IntegerType::get(32),
- name("ftoiy"));
- Value *icastz = m_builder.CreateFPToSI(vec[2], IntegerType::get(32),
- name("ftoiz"));
- Value *icastw = m_builder.CreateFPToSI(vec[3], IntegerType::get(32),
- name("ftoiw"));
- Value *fx = m_builder.CreateSIToFP(icastx, Type::FloatTy,
- name("fx"));
- Value *fy = m_builder.CreateSIToFP(icasty, Type::FloatTy,
- name("fy"));
- Value *fz = m_builder.CreateSIToFP(icastz, Type::FloatTy,
- name("fz"));
- Value *fw = m_builder.CreateSIToFP(icastw, Type::FloatTy,
- name("fw"));
- return vectorFromVals(fx, fy, fz, fw);
-}
-
-llvm::Value * Instructions::x2d(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3)
-{
- std::vector<llvm::Value*> vec1 = extractVector(in1);
- std::vector<llvm::Value*> vec2 = extractVector(in2);
- std::vector<llvm::Value*> vec3 = extractVector(in3);
-
- Value *x2x3 = m_builder.CreateMul( vec2[0], vec3[0], name("x2x3"));
- Value *y2y3 = m_builder.CreateMul( vec2[1], vec3[1], name("y2y3"));
- Value *x1px2x3 = m_builder.CreateAdd (vec1[0], x2x3, name("x1 + x2x3"));
- Value *x1px2x3py2y3 = m_builder.CreateAdd (x1px2x3, y2y3, name("x1 + x2x3 + y2y3"));
-
- Value *x2z3 = m_builder.CreateMul( vec2[0], vec3[2], name("x2z3"));
- Value *y2w3 = m_builder.CreateMul( vec2[1], vec3[3], name("y2w3"));
- Value *y1px2z3 = m_builder.CreateAdd (vec1[1], x2z3, name("y1 + x2z3"));
- Value *y1px2z3py2w3 = m_builder.CreateAdd (y1px2z3, y2w3, name("y1 + x2z3 + y2w3"));
-
- return vectorFromVals(x1px2x3py2y3, y1px2z3py2w3, x1px2x3py2y3, y1px2z3py2w3);
-}
-
-void Instructions::printVector(llvm::Value *val)
-{
- static const char *frmt = "Vector is [%f, %f, %f, %f]\x0A";
-
- if (!m_fmtPtr) {
- Constant *format = ConstantArray::get(frmt, true);
- ArrayType *arrayTy = ArrayType::get(IntegerType::get(8), strlen(frmt) + 1);
- GlobalVariable* globalFormat = new GlobalVariable(
- /*Type=*/arrayTy,
- /*isConstant=*/true,
- /*Linkage=*/GlobalValue::InternalLinkage,
- /*Initializer=*/0, // has initializer, specified below
- /*Name=*/name(".str"),
- m_mod);
- globalFormat->setInitializer(format);
-
- Constant* const_int0 = Constant::getNullValue(IntegerType::get(32));
- std::vector<Constant*> const_ptr_21_indices;
- const_ptr_21_indices.push_back(const_int0);
- const_ptr_21_indices.push_back(const_int0);
- m_fmtPtr = ConstantExpr::getGetElementPtr(globalFormat,
- &const_ptr_21_indices[0], const_ptr_21_indices.size());
- }
-
- Function *func_printf = m_mod->getFunction("printf");
- if (!func_printf)
- func_printf = declarePrintf();
- assert(func_printf);
- std::vector<llvm::Value*> vec = extractVector(val);
- Value *dx = m_builder.CreateFPExt(vec[0], Type::DoubleTy, name("dx"));
- Value *dy = m_builder.CreateFPExt(vec[1], Type::DoubleTy, name("dy"));
- Value *dz = m_builder.CreateFPExt(vec[2], Type::DoubleTy, name("dz"));
- Value *dw = m_builder.CreateFPExt(vec[3], Type::DoubleTy, name("dw"));
- std::vector<Value*> params;
- params.push_back(m_fmtPtr);
- params.push_back(dx);
- params.push_back(dy);
- params.push_back(dz);
- params.push_back(dw);
- CallInst *call = m_builder.CreateCall(func_printf, params.begin(), params.end(),
- name("printf"));
- call->setCallingConv(CallingConv::C);
- call->setTailCall(true);
-}
-
-const char * Instructions::name(const char *prefix)
-{
- ++m_idx;
- snprintf(m_name, 32, "%s%d", prefix, m_idx);
- return m_name;
-}
-
-llvm::Value * Instructions::callCeil(llvm::Value *val)
-{
- if (!m_llvmCeil) {
- // predeclare the intrinsic
- std::vector<const Type*> ceilArgs;
- ceilArgs.push_back(Type::FloatTy);
- AttrListPtr ceilPal;
- FunctionType* ceilType = FunctionType::get(
- /*Result=*/Type::FloatTy,
- /*Params=*/ceilArgs,
- /*isVarArg=*/false);
- m_llvmCeil = Function::Create(
- /*Type=*/ceilType,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"ceilf", m_mod);
- m_llvmCeil->setCallingConv(CallingConv::C);
- m_llvmCeil->setAttributes(ceilPal);
- }
- CallInst *call = m_builder.CreateCall(m_llvmCeil, val,
- name("ceilf"));
- call->setCallingConv(CallingConv::C);
- call->setTailCall(false);
- return call;
-}
-
-llvm::Value *Instructions::callFAbs(llvm::Value *val)
-{
- if (!m_llvmFAbs) {
- // predeclare the intrinsic
- std::vector<const Type*> fabsArgs;
- fabsArgs.push_back(Type::FloatTy);
- AttrListPtr fabsPal;
- FunctionType* fabsType = FunctionType::get(
- /*Result=*/Type::FloatTy,
- /*Params=*/fabsArgs,
- /*isVarArg=*/false);
- m_llvmFAbs = Function::Create(
- /*Type=*/fabsType,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"fabs", m_mod);
- m_llvmFAbs->setCallingConv(CallingConv::C);
- m_llvmFAbs->setAttributes(fabsPal);
- }
- CallInst *call = m_builder.CreateCall(m_llvmFAbs, val,
- name("fabs"));
- call->setCallingConv(CallingConv::C);
- call->setTailCall(false);
- return call;
-}
-
-llvm::Value * Instructions::callFExp(llvm::Value *val)
-{
- if (!m_llvmFexp) {
- // predeclare the intrinsic
- std::vector<const Type*> fexpArgs;
- fexpArgs.push_back(Type::FloatTy);
- AttrListPtr fexpPal;
- FunctionType* fexpType = FunctionType::get(
- /*Result=*/Type::FloatTy,
- /*Params=*/fexpArgs,
- /*isVarArg=*/false);
- m_llvmFexp = Function::Create(
- /*Type=*/fexpType,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"expf", m_mod);
- m_llvmFexp->setCallingConv(CallingConv::C);
- m_llvmFexp->setAttributes(fexpPal);
- }
- CallInst *call = m_builder.CreateCall(m_llvmFexp, val,
- name("expf"));
- call->setCallingConv(CallingConv::C);
- call->setTailCall(false);
- return call;
-}
-
-llvm::Value * Instructions::callFLog(llvm::Value *val)
-{
- if (!m_llvmFlog) {
- // predeclare the intrinsic
- std::vector<const Type*> flogArgs;
- flogArgs.push_back(Type::FloatTy);
- AttrListPtr flogPal;
- FunctionType* flogType = FunctionType::get(
- /*Result=*/Type::FloatTy,
- /*Params=*/flogArgs,
- /*isVarArg=*/false);
- m_llvmFlog = Function::Create(
- /*Type=*/flogType,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"logf", m_mod);
- m_llvmFlog->setCallingConv(CallingConv::C);
- m_llvmFlog->setAttributes(flogPal);
- }
- CallInst *call = m_builder.CreateCall(m_llvmFlog, val,
- name("logf"));
- call->setCallingConv(CallingConv::C);
- call->setTailCall(false);
- return call;
-}
-
-llvm::Value * Instructions::callFloor(llvm::Value *val)
-{
- if (!m_llvmFloor) {
- // predeclare the intrinsic
- std::vector<const Type*> floorArgs;
- floorArgs.push_back(Type::FloatTy);
- AttrListPtr floorPal;
- FunctionType* floorType = FunctionType::get(
- /*Result=*/Type::FloatTy,
- /*Params=*/floorArgs,
- /*isVarArg=*/false);
- m_llvmFloor = Function::Create(
- /*Type=*/floorType,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"floorf", m_mod);
- m_llvmFloor->setCallingConv(CallingConv::C);
- m_llvmFloor->setAttributes(floorPal);
- }
- CallInst *call = m_builder.CreateCall(m_llvmFloor, val,
- name("floorf"));
- call->setCallingConv(CallingConv::C);
- call->setTailCall(false);
- return call;
-}
-
-llvm::Value *Instructions::callFSqrt(llvm::Value *val)
-{
- if (!m_llvmFSqrt) {
- // predeclare the intrinsic
- std::vector<const Type*> fsqrtArgs;
- fsqrtArgs.push_back(Type::FloatTy);
- AttrListPtr fsqrtPal;
- FunctionType* fsqrtType = FunctionType::get(
- /*Result=*/Type::FloatTy,
- /*Params=*/fsqrtArgs,
- /*isVarArg=*/false);
- m_llvmFSqrt = Function::Create(
- /*Type=*/fsqrtType,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"llvm.sqrt.f32", m_mod);
- m_llvmFSqrt->setCallingConv(CallingConv::C);
- m_llvmFSqrt->setAttributes(fsqrtPal);
- }
- CallInst *call = m_builder.CreateCall(m_llvmFSqrt, val,
- name("sqrt"));
- call->setCallingConv(CallingConv::C);
- call->setTailCall(false);
- return call;
-}
-
-llvm::Value * Instructions::callPow(llvm::Value *val1, llvm::Value *val2)
-{
- if (!m_llvmPow) {
- // predeclare the intrinsic
- std::vector<const Type*> powArgs;
- powArgs.push_back(Type::FloatTy);
- powArgs.push_back(Type::FloatTy);
- AttrListPtr powPal;
- FunctionType* powType = FunctionType::get(
- /*Result=*/Type::FloatTy,
- /*Params=*/powArgs,
- /*isVarArg=*/false);
- m_llvmPow = Function::Create(
- /*Type=*/powType,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"llvm.pow.f32", m_mod);
- m_llvmPow->setCallingConv(CallingConv::C);
- m_llvmPow->setAttributes(powPal);
- }
- std::vector<Value*> params;
- params.push_back(val1);
- params.push_back(val2);
- CallInst *call = m_builder.CreateCall(m_llvmPow, params.begin(), params.end(),
- name("pow"));
- call->setCallingConv(CallingConv::C);
- call->setTailCall(false);
- return call;
-}
-
-llvm::Value * Instructions::vectorFromVals(llvm::Value *x, llvm::Value *y,
- llvm::Value *z, llvm::Value *w)
-{
- Constant *const_vec = Constant::getNullValue(m_floatVecType);
- Value *res = m_builder.CreateInsertElement(const_vec, x,
- m_storage->constantInt(0),
- name("vecx"));
- res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1),
- name("vecxy"));
- res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2),
- name("vecxyz"));
- if (w)
- res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3),
- name("vecxyzw"));
- return res;
-}
-
-llvm::Value * Instructions::constVector(float x, float y, float z, float w)
-{
- std::vector<Constant*> vec(4);
- vec[0] = ConstantFP::get(APFloat(x));
- vec[1] = ConstantFP::get(APFloat(y));
- vec[2] = ConstantFP::get(APFloat(z));
- vec[3] = ConstantFP::get(APFloat(w));
- return ConstantVector::get(m_floatVecType, vec);
-}
-
-llvm::Function * Instructions::declarePrintf()
-{
- std::vector<const Type*> args;
- AttrListPtr params;
- FunctionType* funcTy = FunctionType::get(
- /*Result=*/IntegerType::get(32),
- /*Params=*/args,
- /*isVarArg=*/true);
- Function* func_printf = Function::Create(
- /*Type=*/funcTy,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/"printf", m_mod);
- func_printf->setCallingConv(CallingConv::C);
- func_printf->setAttributes(params);
- return func_printf;
-}
-
-llvm::Function * Instructions::declareFunc(int label)
-{
- PointerType *vecPtr = PointerType::getUnqual(m_floatVecType);
- std::vector<const Type*> args;
- args.push_back(vecPtr);
- args.push_back(vecPtr);
- args.push_back(vecPtr);
- args.push_back(vecPtr);
- AttrListPtr params;
- FunctionType *funcType = FunctionType::get(
- /*Result=*/Type::VoidTy,
- /*Params=*/args,
- /*isVarArg=*/false);
- std::string name = createFuncName(label);
- Function *func = Function::Create(
- /*Type=*/funcType,
- /*Linkage=*/GlobalValue::ExternalLinkage,
- /*Name=*/name.c_str(), m_mod);
- func->setCallingConv(CallingConv::C);
- func->setAttributes(params);
- return func;
-}
-
-llvm::Function * Instructions::findFunction(int label)
-{
- llvm::Function *func = m_functions[label];
- if (!func) {
- func = declareFunc(label);
- m_functions[label] = func;
- }
- return func;
-}
-
-std::vector<llvm::Value*> Instructions::extractVector(llvm::Value *vec)
-{
- std::vector<llvm::Value*> elems(4);
- elems[0] = m_builder.CreateExtractElement(vec, m_storage->constantInt(0),
- name("x"));
- elems[1] = m_builder.CreateExtractElement(vec, m_storage->constantInt(1),
- name("y"));
- elems[2] = m_builder.CreateExtractElement(vec, m_storage->constantInt(2),
- name("z"));
- elems[3] = m_builder.CreateExtractElement(vec, m_storage->constantInt(3),
- name("w"));
- return elems;
-}
-
-
-#endif //MESA_LLVM
-
-