instructions.cpp

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  *
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  *
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  *
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  *
00026  **************************************************************************/
00027 
00028  /*
00029   * Authors:
00030   *   Zack Rusin zack@tungstengraphics.com
00031   */
00032 #ifdef MESA_LLVM
00033 
00034 #include "instructions.h"
00035 
00036 #include "storage.h"
00037 
00038 #include "util/u_memory.h"
00039 
00040 #include <llvm/CallingConv.h>
00041 #include <llvm/Constants.h>
00042 #include <llvm/DerivedTypes.h>
00043 #include <llvm/Function.h>
00044 #include <llvm/InstrTypes.h>
00045 #include <llvm/Instructions.h>
00046 #include <llvm/ParameterAttributes.h>
00047 #include <llvm/Support/MemoryBuffer.h>
00048 #include <llvm/Bitcode/ReaderWriter.h>
00049 
00050 #include <sstream>
00051 #include <fstream>
00052 #include <iostream>
00053 
00054 using namespace llvm;
00055 
00056 #include "gallivm_builtins.cpp"
00057 
00058 #if 0
00059 llvm::Value *arrayFromChannels(std::vector<llvm::Value*> &vals)
00060 {
00061    VectorType *vectorType = VectorType::get(Type::FloatTy, 4);
00062    ArrayType *vectorArray = ArrayType::get(vectorType, 4);
00063 }
00064 #endif
00065 
00066 static inline std::string createFuncName(int label)
00067 {
00068    std::ostringstream stream;
00069    stream << "function";
00070    stream << label;
00071    return stream.str();
00072 }
00073 
00074 Instructions::Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block,
00075                            Storage *storage)
00076    :  m_mod(mod), m_func(func), m_builder(block), m_idx(0),
00077       m_storage(storage)
00078 {
00079    m_floatVecType = VectorType::get(Type::FloatTy, 4);
00080 
00081    m_llvmFSqrt = 0;
00082    m_llvmFAbs  = 0;
00083    m_llvmPow   = 0;
00084    m_llvmFloor = 0;
00085    m_llvmFlog  = 0;
00086    m_llvmFexp  = 0;
00087    m_llvmLit  = 0;
00088    m_fmtPtr = 0;
00089 
00090    MemoryBuffer *buffer = MemoryBuffer::getMemBuffer(
00091       (const char*)&llvm_builtins_data[0],
00092       (const char*)&llvm_builtins_data[Elements(llvm_builtins_data)-1]);
00093    m_mod = ParseBitcodeFile(buffer);
00094 }
00095 
00096 llvm::BasicBlock * Instructions::currentBlock() const
00097 {
00098    return m_builder.GetInsertBlock();
00099 }
00100 
00101 llvm::Value * Instructions::abs(llvm::Value *in)
00102 {
00103    std::vector<llvm::Value*> vec = extractVector(in);
00104    Value *xabs  = callFAbs(vec[0]);
00105    Value *yabs  = callFAbs(vec[1]);
00106    Value *zabs  = callFAbs(vec[2]);
00107    Value *wabs  = callFAbs(vec[3]);
00108    return vectorFromVals(xabs, yabs, zabs, wabs);
00109 }
00110 
00111 llvm::Value * Instructions::add(llvm::Value *in1, llvm::Value *in2)
00112 {
00113    return m_builder.CreateAdd(in1, in2, name("add"));
00114 }
00115 
00116 llvm::Value * Instructions::arl(llvm::Value *in)
00117 {
00118    return floor(in);
00119 }
00120 
00121 void Instructions::beginLoop()
00122 {
00123    BasicBlock *begin = BasicBlock::Create(name("loop"), m_func,0);
00124    BasicBlock *end = BasicBlock::Create(name("endloop"), m_func,0);
00125 
00126    m_builder.CreateBr(begin);
00127    Loop loop;
00128    loop.begin = begin;
00129    loop.end   = end;
00130    m_builder.SetInsertPoint(begin);
00131    m_loopStack.push(loop);
00132 }
00133 
00134 void Instructions::bgnSub(unsigned label)
00135 {
00136    llvm::Function *func = findFunction(label);
00137 
00138    Function::arg_iterator args = func->arg_begin();
00139    Value *ptr_INPUT = args++;
00140    ptr_INPUT->setName("INPUT");
00141    m_storage->pushArguments(ptr_INPUT);
00142 
00143    llvm::BasicBlock *entry = BasicBlock::Create("entry", func, 0);
00144 
00145    m_func = func;
00146    m_builder.SetInsertPoint(entry);
00147 }
00148 
00149 void Instructions::brk()
00150 {
00151    assert(!m_loopStack.empty());
00152    BasicBlock *unr = BasicBlock::Create(name("unreachable"), m_func,0);
00153    m_builder.CreateBr(m_loopStack.top().end);
00154    m_builder.SetInsertPoint(unr);
00155 }
00156 
00157 void Instructions::cal(int label, llvm::Value *input)
00158 {
00159    std::vector<Value*> params;
00160    params.push_back(input);
00161    llvm::Function *func = findFunction(label);
00162 
00163    m_builder.CreateCall(func, params.begin(), params.end());
00164 }
00165 
00166 llvm::Value * Instructions::ceil(llvm::Value *in)
00167 {
00168    std::vector<llvm::Value*> vec = extractVector(in);
00169    return vectorFromVals(callCeil(vec[0]), callCeil(vec[1]),
00170                          callCeil(vec[2]), callCeil(vec[3]));
00171 }
00172 
00173 llvm::Value * Instructions::clamp(llvm::Value *in1)
00174 {
00175    llvm::Value *zero = constVector(0.0f, 0.0f, 0.0f, 0.0f);
00176    llvm::Value *one = constVector(1.0f, 1.0f, 1.0f, 1.0f);
00177    return min( max(zero, in1), one);
00178 }
00179 
00180 llvm::Value * Instructions::cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3)
00181 {
00182    llvm::Function *func = m_mod->getFunction("cmp");
00183    assert(func);
00184 
00185    std::vector<Value*> params;
00186    params.push_back(in1);
00187    params.push_back(in2);
00188    params.push_back(in3);
00189    CallInst *call = m_builder.CreateCall(func, params.begin(), params.end(), name("cmpres"));
00190    call->setTailCall(false);
00191    return call;
00192 }
00193 
00194 llvm::Value * Instructions::cnd(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3)
00195 {
00196    std::vector<llvm::Value*> vec1 = extractVector(in1);
00197    std::vector<llvm::Value*> vec2 = extractVector(in2);
00198    std::vector<llvm::Value*> vec3 = extractVector(in3);
00199    Constant *half = ConstantFP::get(APFloat(0.5f));
00200 
00201    Value *xcmp  = m_builder.CreateFCmpOGT(vec1[0], half, name("xcmp"));
00202    Value *selx = m_builder.CreateSelect(xcmp, vec2[0], vec3[0],
00203                                         name("selx"));
00204 
00205    Value *ycmp  = m_builder.CreateFCmpOGT(vec1[1], half, name("ycmp"));
00206    Value *sely = m_builder.CreateSelect(ycmp, vec2[1], vec3[1],
00207                                         name("sely"));
00208 
00209    Value *zcmp  = m_builder.CreateFCmpOGT(vec1[2], half, name("zcmp"));
00210    Value *selz = m_builder.CreateSelect(zcmp, vec2[2], vec3[2],
00211                                         name("selz"));
00212 
00213    Value *wcmp  = m_builder.CreateFCmpOGT(vec1[3], half, name("wcmp"));
00214    Value *selw = m_builder.CreateSelect(wcmp, vec2[3], vec3[3],
00215                                         name("selw"));
00216 
00217    return vectorFromVals(selx, sely, selz, selw);
00218 }
00219 
00220 llvm::Value * Instructions::cnd0(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3)
00221 {
00222    std::vector<llvm::Value*> vec1 = extractVector(in1);
00223    std::vector<llvm::Value*> vec2 = extractVector(in2);
00224    std::vector<llvm::Value*> vec3 = extractVector(in3);
00225    Constant *zero = Constant::getNullValue(Type::FloatTy);
00226 
00227    Value *xcmp  = m_builder.CreateFCmpOGE(vec1[0], zero, name("xcmp"));
00228    Value *selx = m_builder.CreateSelect(xcmp, vec2[0], vec3[0],
00229                                         name("selx"));
00230 
00231    Value *ycmp  = m_builder.CreateFCmpOGE(vec1[1], zero, name("ycmp"));
00232    Value *sely = m_builder.CreateSelect(ycmp, vec2[1], vec3[1],
00233                                         name("sely"));
00234 
00235    Value *zcmp  = m_builder.CreateFCmpOGE(vec1[2], zero, name("zcmp"));
00236    Value *selz = m_builder.CreateSelect(zcmp, vec2[2], vec3[2],
00237                                         name("selz"));
00238 
00239    Value *wcmp  = m_builder.CreateFCmpOGE(vec1[3], zero, name("wcmp"));
00240    Value *selw = m_builder.CreateSelect(wcmp, vec2[3], vec3[3],
00241                                         name("selw"));
00242 
00243    return vectorFromVals(selx, sely, selz, selw);
00244 }
00245 
00246 llvm::Value * Instructions::cos(llvm::Value *in)
00247 {
00248 #if 0
00249    llvm::Function *func = m_mod->getFunction("vcos");
00250    assert(func);
00251 
00252    CallInst *call = m_builder.CreateCall(func, in, name("cosres"));
00253    call->setTailCall(false);
00254    return call;
00255 #else
00256    std::vector<llvm::Value*> elems = extractVector(in);
00257    Function *func = m_mod->getFunction("cosf");
00258    assert(func);
00259    CallInst *cos = m_builder.CreateCall(func, elems[0], name("cosres"));
00260    cos->setCallingConv(CallingConv::C);
00261    cos->setTailCall(true);
00262    return vectorFromVals(cos, cos, cos, cos);
00263 #endif
00264 }
00265 
00266 llvm::Value * Instructions::cross(llvm::Value *in1, llvm::Value *in2)
00267 {
00268    Value *x1 = m_builder.CreateExtractElement(in1,
00269                                               m_storage->constantInt(0),
00270                                               name("x1"));
00271    Value *y1 = m_builder.CreateExtractElement(in1,
00272                                               m_storage->constantInt(1),
00273                                               name("y1"));
00274    Value *z1 = m_builder.CreateExtractElement(in1,
00275                                               m_storage->constantInt(2),
00276                                               name("z1"));
00277 
00278    Value *x2 = m_builder.CreateExtractElement(in2,
00279                                               m_storage->constantInt(0),
00280                                               name("x2"));
00281    Value *y2 = m_builder.CreateExtractElement(in2,
00282                                               m_storage->constantInt(1),
00283                                               name("y2"));
00284    Value *z2 = m_builder.CreateExtractElement(in2,
00285                                               m_storage->constantInt(2),
00286                                               name("z2"));
00287    Value *y1z2 = mul(y1, z2);
00288    Value *z1y2 = mul(z1, y2);
00289 
00290    Value *z1x2 = mul(z1, x2);
00291    Value *x1z2 = mul(x1, z2);
00292 
00293    Value *x1y2 = mul(x1, y2);
00294    Value *y1x2 = mul(y1, x2);
00295 
00296    return vectorFromVals(sub(y1z2, z1y2), sub(z1x2, x1z2), sub(x1y2, y1x2));
00297 }
00298 
00299 llvm::Value * Instructions::ddx(llvm::Value *in)
00300 {
00301    // FIXME
00302    assert(0);
00303 }
00304 
00305 llvm::Value * Instructions::ddy(llvm::Value *in)
00306 {
00307    // FIXME
00308    assert(0);
00309 }
00310 
00311 llvm::Value * Instructions::div(llvm::Value *in1, llvm::Value *in2)
00312 {
00313    return m_builder.CreateFDiv(in1, in2, name("div"));
00314 }
00315 
00316 llvm::Value * Instructions::dot2add(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3)
00317 {
00318    Value *mulRes = mul(in1, in2);
00319    Value *x = m_builder.CreateExtractElement(mulRes,
00320                                                           m_storage->constantInt(0),
00321                                                           name("extractx"));
00322    Value *y = m_builder.CreateExtractElement(mulRes,
00323                                                           m_storage->constantInt(1),
00324                                                           name("extracty"));
00325    Value *z = m_builder.CreateExtractElement(in3,
00326                                                           m_storage->constantInt(2),
00327                                                           name("extractz"));
00328    Value *xy = m_builder.CreateAdd(x, y,name("xy"));
00329    Value *dot2add = m_builder.CreateAdd(xy, z, name("dot2add"));
00330    return vectorFromVals(dot2add, dot2add, dot2add, dot2add);
00331 }
00332 
00333 llvm::Value * Instructions::dp2(llvm::Value *in1, llvm::Value *in2)
00334 {
00335    Value *mulRes = mul(in1, in2);
00336    Value *x = m_builder.CreateExtractElement(mulRes,
00337                                                           m_storage->constantInt(0),
00338                                                           name("extractx"));
00339    Value *y = m_builder.CreateExtractElement(mulRes,
00340                                                           m_storage->constantInt(1),
00341                                                           name("extracty"));
00342    Value *xy = m_builder.CreateAdd(x, y,name("xy"));
00343    return vectorFromVals(xy, xy, xy, xy);
00344 }
00345 
00346 llvm::Value * Instructions::dp3(llvm::Value *in1, llvm::Value *in2)
00347 {
00348    Value *mulRes = mul(in1, in2);
00349    Value *x = m_builder.CreateExtractElement(mulRes,
00350                                                           m_storage->constantInt(0),
00351                                                           name("extractx"));
00352    Value *y = m_builder.CreateExtractElement(mulRes,
00353                                                           m_storage->constantInt(1),
00354                                                           name("extracty"));
00355    Value *z = m_builder.CreateExtractElement(mulRes,
00356                                                           m_storage->constantInt(2),
00357                                                           name("extractz"));
00358    Value *xy = m_builder.CreateAdd(x, y,name("xy"));
00359    Value *dot3 = m_builder.CreateAdd(xy, z, name("dot3"));
00360    return vectorFromVals(dot3, dot3, dot3, dot3);
00361 }
00362 
00363 llvm::Value * Instructions::dp4(llvm::Value *in1, llvm::Value *in2)
00364 {
00365    Value *mulRes = mul(in1, in2);
00366    std::vector<llvm::Value*> vec = extractVector(mulRes);
00367    Value *xy = m_builder.CreateAdd(vec[0], vec[1], name("xy"));
00368    Value *xyz = m_builder.CreateAdd(xy, vec[2], name("xyz"));
00369    Value *dot4 = m_builder.CreateAdd(xyz, vec[3], name("dot4"));
00370    return vectorFromVals(dot4, dot4, dot4, dot4);
00371 }
00372 
00373 llvm::Value * Instructions::dph(llvm::Value *in1, llvm::Value *in2)
00374 {
00375    Value *mulRes = mul(in1, in2);
00376    std::vector<llvm::Value*> vec1 = extractVector(mulRes);
00377    Value *xy = m_builder.CreateAdd(vec1[0], vec1[1], name("xy"));
00378    Value *xyz = m_builder.CreateAdd(xy, vec1[2], name("xyz"));
00379    Value *dph = m_builder.CreateAdd(xyz, vec1[3], name("dph"));
00380    return vectorFromVals(dph, dph, dph, dph);
00381 }
00382 
00383 llvm::Value * Instructions::dst(llvm::Value *in1, llvm::Value *in2)
00384 {
00385    Value *y1 = m_builder.CreateExtractElement(in1,
00386                                               m_storage->constantInt(1),
00387                                               name("y1"));
00388    Value *z = m_builder.CreateExtractElement(in1,
00389                                              m_storage->constantInt(2),
00390                                              name("z"));
00391    Value *y2 = m_builder.CreateExtractElement(in2,
00392                                               m_storage->constantInt(1),
00393                                               name("y2"));
00394    Value *w = m_builder.CreateExtractElement(in2,
00395                                              m_storage->constantInt(3),
00396                                              name("w"));
00397    Value *ry = m_builder.CreateMul(y1, y2, name("tyuy"));
00398    return vectorFromVals(ConstantFP::get(APFloat(1.f)),
00399                          ry, z, w);
00400 }
00401 
00402 void Instructions::elseop()
00403 {
00404    assert(!m_ifStack.empty());
00405    BasicBlock *ifend = BasicBlock::Create(name("ifend"), m_func,0);
00406    m_builder.CreateBr(ifend);
00407    m_builder.SetInsertPoint(m_ifStack.top());
00408    currentBlock()->setName(name("ifelse"));
00409    m_ifStack.pop();
00410    m_ifStack.push(ifend);
00411 }
00412 
00413 void Instructions::endif()
00414 {
00415    assert(!m_ifStack.empty());
00416    m_builder.CreateBr(m_ifStack.top());
00417    m_builder.SetInsertPoint(m_ifStack.top());
00418    m_ifStack.pop();
00419 }
00420 
00421 void Instructions::endLoop()
00422 {
00423    assert(!m_loopStack.empty());
00424    Loop loop = m_loopStack.top();
00425    m_builder.CreateBr(loop.begin);
00426    loop.end->moveAfter(currentBlock());
00427    m_builder.SetInsertPoint(loop.end);
00428    m_loopStack.pop();
00429 }
00430 
00431 void Instructions::end()
00432 {
00433    m_builder.CreateRetVoid();
00434 }
00435 
00436 void Instructions::endSub()
00437 {
00438    m_func = 0;
00439    m_builder.SetInsertPoint(0);
00440 }
00441 
00442 llvm::Value * Instructions::exp(llvm::Value *in)
00443 {
00444    std::vector<llvm::Value*> vec = extractVector(in);
00445    return vectorFromVals(callFExp(vec[0]), callFExp(vec[1]),
00446                              callFExp(vec[2]), callFExp(vec[3]));
00447 }
00448 
00449 llvm::Value * Instructions::ex2(llvm::Value *in)
00450 {
00451    llvm::Value *val = callPow(ConstantFP::get(APFloat(2.f)),
00452                               m_builder.CreateExtractElement(
00453                                  in, m_storage->constantInt(0),
00454                                  name("x1")));
00455    return vectorFromVals(val, val, val, val);
00456 }
00457 
00458 llvm::Value * Instructions::floor(llvm::Value *in)
00459 {
00460    std::vector<llvm::Value*> vec = extractVector(in);
00461    return vectorFromVals(callFloor(vec[0]), callFloor(vec[1]),
00462                          callFloor(vec[2]), callFloor(vec[3]));
00463 }
00464 
00465 llvm::Value * Instructions::frc(llvm::Value *in)
00466 {
00467    llvm::Value *flr = floor(in);
00468    return sub(in, flr);
00469 }
00470 
00471 void Instructions::ifop(llvm::Value *in)
00472 {
00473    BasicBlock *ifthen = BasicBlock::Create(name("ifthen"), m_func,0);
00474    BasicBlock *ifend = BasicBlock::Create(name("ifthenend"), m_func,0);
00475 
00476    //BasicBlock *yblock = new BasicBlock(name("yblock"), m_func,0);
00477    //BasicBlock *zblock = new BasicBlock(name("zblock"), m_func,0);
00478    //BasicBlock *wblock = new BasicBlock(name("wblock"), m_func,0);
00479 
00480    Constant *float0 = Constant::getNullValue(Type::FloatTy);
00481 
00482    Value *x = m_builder.CreateExtractElement(in, m_storage->constantInt(0),
00483                                              name("extractx"));
00484    Value *xcmp = m_builder.CreateFCmpUNE(x, float0, name("xcmp"));
00485    m_builder.CreateCondBr(xcmp, ifthen, ifend);
00486    //m_builder.SetInsertPoint(yblock);
00487 
00488    m_builder.SetInsertPoint(ifthen);
00489    m_ifStack.push(ifend);
00490 }
00491 
00492 llvm::Value * Instructions::kil(llvm::Value *in)
00493 {
00494    llvm::Function *func = m_mod->getFunction("kil");
00495    assert(func);
00496 
00497    CallInst *call = m_builder.CreateCall(func, in, name("kilpres"));
00498    call->setTailCall(false);
00499    return call;
00500 }
00501 
00502 llvm::Value * Instructions::lerp(llvm::Value *in1, llvm::Value *in2,
00503                                  llvm::Value *in3)
00504 {
00505    llvm::Value *m = mul(in1, in2);
00506    llvm::Value *vec1 = constVector(1.f, 1.f, 1.f, 1.f);
00507    llvm::Value *s = sub(vec1, in1);
00508    return add(m, mul(s, in3));
00509 }
00510 
00511 llvm::Value * Instructions::lg2(llvm::Value *in)
00512 {
00513    std::vector<llvm::Value*> vec = extractVector(in);
00514    llvm::Value *const_vec = constVector(1.442695f, 1.442695f,
00515                                         1.442695f, 1.442695f);
00516    return mul(vectorFromVals(callFLog(vec[0]), callFLog(vec[1]),
00517                              callFLog(vec[2]), callFLog(vec[3])), const_vec);
00518 }
00519 
00520 llvm::Value * Instructions::lit(llvm::Value *in)
00521 {
00522    if (!m_llvmLit) {
00523       m_llvmLit = m_mod->getFunction("lit");
00524    }
00525    CallInst *call = m_builder.CreateCall(m_llvmLit, in, name("litres"));
00526    call->setCallingConv(CallingConv::C);
00527    call->setTailCall(false);
00528    return call;
00529 }
00530 
00531 llvm::Value * Instructions::log(llvm::Value *in)
00532 {
00533    std::vector<llvm::Value*> vec = extractVector(in);
00534    return vectorFromVals(callFLog(vec[0]), callFLog(vec[1]),
00535                              callFLog(vec[2]), callFLog(vec[3]));
00536 }
00537 
00538 llvm::Value * Instructions::madd(llvm::Value *in1, llvm::Value *in2,
00539                                  llvm::Value *in3)
00540 {
00541    Value *mulRes = mul(in1, in2);
00542    return add(mulRes, in3);
00543 }
00544 
00545 llvm::Value * Instructions::max(llvm::Value *in1, llvm::Value *in2)
00546 {
00547    std::vector<llvm::Value*> vec1 = extractVector(in1);
00548    std::vector<llvm::Value*> vec2 = extractVector(in2);
00549 
00550    Value *xcmp  = m_builder.CreateFCmpOGT(vec1[0], vec2[0],
00551                                           name("xcmp"));
00552    Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0],
00553                                         name("selx"));
00554 
00555    Value *ycmp  = m_builder.CreateFCmpOGT(vec1[1], vec2[1],
00556                                           name("ycmp"));
00557    Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1],
00558                                         name("sely"));
00559 
00560    Value *zcmp  = m_builder.CreateFCmpOGT(vec1[2], vec2[2],
00561                                           name("zcmp"));
00562    Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2],
00563                                         name("selz"));
00564 
00565    Value *wcmp  = m_builder.CreateFCmpOGT(vec1[3], vec2[3],
00566                                           name("wcmp"));
00567    Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3],
00568                                         name("selw"));
00569 
00570    return vectorFromVals(selx, sely, selz, selw);
00571 }
00572 
00573 llvm::Value * Instructions::min(llvm::Value *in1, llvm::Value *in2)
00574 {
00575    std::vector<llvm::Value*> vec1 = extractVector(in1);
00576    std::vector<llvm::Value*> vec2 = extractVector(in2);
00577 
00578    Value *xcmp  = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp"));
00579    Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0],
00580                                         name("selx"));
00581 
00582    Value *ycmp  = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp"));
00583    Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1],
00584                                         name("sely"));
00585 
00586    Value *zcmp  = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp"));
00587    Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2],
00588                                         name("selz"));
00589 
00590    Value *wcmp  = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp"));
00591    Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3],
00592                                         name("selw"));
00593 
00594    return vectorFromVals(selx, sely, selz, selw);
00595 }
00596 
00597 llvm::Value * Instructions::mul(llvm::Value *in1, llvm::Value *in2)
00598 {
00599    return m_builder.CreateMul(in1, in2, name("mul"));
00600 }
00601 
00602 llvm::Value * Instructions::neg(llvm::Value *in)
00603 {
00604    Value *neg = m_builder.CreateNeg(in, name("neg"));
00605    return neg;
00606 }
00607 
00608 llvm::Value * Instructions::nrm(llvm::Value *in)
00609 {
00610    llvm::Value *v = rsq(in);
00611    return mul(v, in);
00612 }
00613 
00614 llvm::Value * Instructions::pow(llvm::Value *in1, llvm::Value *in2)
00615 {
00616    Value *x1 = m_builder.CreateExtractElement(in1,
00617                                               m_storage->constantInt(0),
00618                                               name("x1"));
00619    Value *x2 = m_builder.CreateExtractElement(in2,
00620                                               m_storage->constantInt(0),
00621                                               name("x2"));
00622    llvm::Value *val = callPow(x1, x2);
00623    return vectorFromVals(val, val, val, val);
00624 }
00625 
00626 llvm::Value * Instructions::rcp(llvm::Value *in1)
00627 {
00628    Value *x1 = m_builder.CreateExtractElement(in1,
00629                                               m_storage->constantInt(0),
00630                                               name("x1"));
00631    Value *res = m_builder.CreateFDiv(ConstantFP::get(APFloat(1.f)),
00632                                      x1, name("rcp"));
00633    return vectorFromVals(res, res, res, res);
00634 }
00635 
00636 llvm::Value * Instructions::rsq(llvm::Value *in1)
00637 {
00638    Value *x = m_builder.CreateExtractElement(in1,
00639                                              m_storage->constantInt(0),
00640                                              name("extractx"));
00641    Value *abs  = callFAbs(x);
00642    Value *sqrt = callFSqrt(abs);
00643 
00644    Value *rsqrt = m_builder.CreateFDiv(ConstantFP::get(APFloat(1.f)),
00645                                        sqrt,
00646                                        name("rsqrt"));
00647    return vectorFromVals(rsqrt, rsqrt, rsqrt, rsqrt);
00648 }
00649 
00650 llvm::Value * Instructions::scs(llvm::Value *in)
00651 {
00652    llvm::Function *func = m_mod->getFunction("scs");
00653    assert(func);
00654 
00655    CallInst *call = m_builder.CreateCall(func, in, name("scsres"));
00656    call->setTailCall(false);
00657    return call;
00658 }
00659 
00660 llvm::Value * Instructions::seq(llvm::Value *in1, llvm::Value *in2)
00661 {
00662    Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
00663    Constant *const0f = Constant::getNullValue(Type::FloatTy);
00664 
00665    std::vector<llvm::Value*> vec1 = extractVector(in1);
00666    std::vector<llvm::Value*> vec2 = extractVector(in2);
00667 
00668    Value *xcmp = m_builder.CreateFCmpOEQ(vec1[0], vec2[0], name("xcmp"));
00669    Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
00670 
00671    Value *ycmp = m_builder.CreateFCmpOEQ(vec1[1], vec2[1], name("ycmp"));
00672    Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
00673 
00674    Value *zcmp = m_builder.CreateFCmpOEQ(vec1[2], vec2[2], name("zcmp"));
00675    Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
00676 
00677    Value *wcmp = m_builder.CreateFCmpOEQ(vec1[3], vec2[3], name("wcmp"));
00678    Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
00679 
00680    return vectorFromVals(x, y, z, w);
00681 }
00682 
00683 llvm::Value * Instructions::sfl(llvm::Value *in1, llvm::Value *in2)
00684 {
00685    Constant *const0f = Constant::getNullValue(Type::FloatTy);
00686 
00687    return vectorFromVals(const0f, const0f, const0f, const0f);
00688 }
00689 
00690 llvm::Value * Instructions::sge(llvm::Value *in1, llvm::Value *in2)
00691 {
00692    Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
00693    Constant *const0f = Constant::getNullValue(Type::FloatTy);
00694 
00695    std::vector<llvm::Value*> vec1 = extractVector(in1);
00696    std::vector<llvm::Value*> vec2 = extractVector(in2);
00697 
00698    Value *xcmp = m_builder.CreateFCmpOGE(vec1[0], vec2[0], name("xcmp"));
00699    Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
00700 
00701    Value *ycmp = m_builder.CreateFCmpOGE(vec1[1], vec2[1], name("ycmp"));
00702    Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
00703 
00704    Value *zcmp = m_builder.CreateFCmpOGE(vec1[2], vec2[2], name("zcmp"));
00705    Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
00706 
00707    Value *wcmp = m_builder.CreateFCmpOGE(vec1[3], vec2[3], name("wcmp"));
00708    Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
00709 
00710    return vectorFromVals(x, y, z, w);
00711 }
00712 
00713 llvm::Value * Instructions::sgt(llvm::Value *in1, llvm::Value *in2)
00714 {
00715    Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
00716    Constant *const0f = Constant::getNullValue(Type::FloatTy);
00717 
00718    std::vector<llvm::Value*> vec1 = extractVector(in1);
00719    std::vector<llvm::Value*> vec2 = extractVector(in2);
00720    Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], name("xcmp"));
00721    Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
00722 
00723    Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], name("ycmp"));
00724    Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
00725 
00726    Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], name("zcmp"));
00727    Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
00728 
00729    Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], name("wcmp"));
00730    Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
00731 
00732    return vectorFromVals(x, y, z, w);
00733 }
00734 
00735 llvm::Value * Instructions::sin(llvm::Value *in)
00736 {
00737    llvm::Function *func = m_mod->getFunction("vsin");
00738    assert(func);
00739 
00740    CallInst *call = m_builder.CreateCall(func, in, name("sinres"));
00741    call->setTailCall(false);
00742    return call;
00743 }
00744 
00745 llvm::Value * Instructions::sle(llvm::Value *in1, llvm::Value *in2)
00746 {
00747    Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
00748    Constant *const0f = Constant::getNullValue(Type::FloatTy);
00749 
00750    std::vector<llvm::Value*> vec1 = extractVector(in1);
00751    std::vector<llvm::Value*> vec2 = extractVector(in2);
00752 
00753    Value *xcmp = m_builder.CreateFCmpOLE(vec1[0], vec2[0], name("xcmp"));
00754    Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
00755 
00756    Value *ycmp = m_builder.CreateFCmpOLE(vec1[1], vec2[1], name("ycmp"));
00757    Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
00758 
00759    Value *zcmp = m_builder.CreateFCmpOLE(vec1[2], vec2[2], name("zcmp"));
00760    Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
00761 
00762    Value *wcmp = m_builder.CreateFCmpOLE(vec1[3], vec2[3], name("wcmp"));
00763    Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
00764 
00765    return vectorFromVals(x, y, z, w);
00766 }
00767 
00768 llvm::Value * Instructions::slt(llvm::Value *in1, llvm::Value *in2)
00769 {
00770    Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
00771    Constant *const0f = Constant::getNullValue(Type::FloatTy);
00772 
00773    std::vector<llvm::Value*> vec1 = extractVector(in1);
00774    std::vector<llvm::Value*> vec2 = extractVector(in2);
00775 
00776    Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp"));
00777    Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
00778 
00779    Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp"));
00780    Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
00781 
00782    Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp"));
00783    Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
00784 
00785    Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp"));
00786    Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
00787 
00788    return vectorFromVals(x, y, z, w);
00789 }
00790 
00791 llvm::Value * Instructions::sne(llvm::Value *in1, llvm::Value *in2)
00792 {
00793    Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
00794    Constant *const0f = Constant::getNullValue(Type::FloatTy);
00795 
00796    std::vector<llvm::Value*> vec1 = extractVector(in1);
00797    std::vector<llvm::Value*> vec2 = extractVector(in2);
00798 
00799    Value *xcmp = m_builder.CreateFCmpONE(vec1[0], vec2[0], name("xcmp"));
00800    Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
00801 
00802    Value *ycmp = m_builder.CreateFCmpONE(vec1[1], vec2[1], name("ycmp"));
00803    Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
00804 
00805    Value *zcmp = m_builder.CreateFCmpONE(vec1[2], vec2[2], name("zcmp"));
00806    Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
00807 
00808    Value *wcmp = m_builder.CreateFCmpONE(vec1[3], vec2[3], name("wcmp"));
00809    Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
00810 
00811    return vectorFromVals(x, y, z, w);
00812 }
00813 
00814 llvm::Value * Instructions::str(llvm::Value *in1, llvm::Value *in2)
00815 {
00816    Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
00817 
00818    return vectorFromVals(const1f, const1f, const1f, const1f);
00819 }
00820 
00821 llvm::Value * Instructions::sub(llvm::Value *in1, llvm::Value *in2)
00822 {
00823    Value *res = m_builder.CreateSub(in1, in2, name("sub"));
00824    return res;
00825 }
00826 
00827 llvm::Value * Instructions::trunc(llvm::Value *in)
00828 {
00829    std::vector<llvm::Value*> vec = extractVector(in);
00830    Value *icastx = m_builder.CreateFPToSI(vec[0], IntegerType::get(32),
00831                                           name("ftoix"));
00832    Value *icasty = m_builder.CreateFPToSI(vec[1], IntegerType::get(32),
00833                                           name("ftoiy"));
00834    Value *icastz = m_builder.CreateFPToSI(vec[2], IntegerType::get(32),
00835                                           name("ftoiz"));
00836    Value *icastw = m_builder.CreateFPToSI(vec[3], IntegerType::get(32),
00837                                           name("ftoiw"));
00838    Value *fx = m_builder.CreateSIToFP(icastx, Type::FloatTy,
00839                                       name("fx"));
00840    Value *fy = m_builder.CreateSIToFP(icasty, Type::FloatTy,
00841                                       name("fy"));
00842    Value *fz = m_builder.CreateSIToFP(icastz, Type::FloatTy,
00843                                       name("fz"));
00844    Value *fw = m_builder.CreateSIToFP(icastw, Type::FloatTy,
00845                                       name("fw"));
00846    return vectorFromVals(fx, fy, fz, fw);
00847 }
00848 
00849 llvm::Value * Instructions::x2d(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3)
00850 {
00851    std::vector<llvm::Value*> vec1 = extractVector(in1);
00852    std::vector<llvm::Value*> vec2 = extractVector(in2);
00853    std::vector<llvm::Value*> vec3 = extractVector(in3);
00854 
00855    Value *x2x3 = m_builder.CreateMul( vec2[0], vec3[0], name("x2x3"));
00856    Value *y2y3 = m_builder.CreateMul( vec2[1], vec3[1], name("y2y3"));
00857    Value *x1px2x3 = m_builder.CreateAdd (vec1[0], x2x3, name("x1 + x2x3"));
00858    Value *x1px2x3py2y3 = m_builder.CreateAdd (x1px2x3, y2y3, name("x1 + x2x3 + y2y3"));
00859 
00860    Value *x2z3 = m_builder.CreateMul( vec2[0], vec3[2], name("x2z3"));
00861    Value *y2w3 = m_builder.CreateMul( vec2[1], vec3[3], name("y2w3"));
00862    Value *y1px2z3 = m_builder.CreateAdd (vec1[1], x2z3, name("y1 + x2z3"));
00863    Value *y1px2z3py2w3 = m_builder.CreateAdd (y1px2z3, y2w3, name("y1 + x2z3 + y2w3"));
00864 
00865    return vectorFromVals(x1px2x3py2y3, y1px2z3py2w3, x1px2x3py2y3, y1px2z3py2w3);
00866 }
00867 
00868 void Instructions::printVector(llvm::Value *val)
00869 {
00870    static const char *frmt = "Vector is [%f, %f, %f, %f]\x0A";
00871 
00872    if (!m_fmtPtr) {
00873       Constant *format = ConstantArray::get(frmt, true);
00874       ArrayType *arrayTy = ArrayType::get(IntegerType::get(8), strlen(frmt) + 1);
00875       GlobalVariable* globalFormat = new GlobalVariable(
00876          /*Type=*/arrayTy,
00877          /*isConstant=*/true,
00878          /*Linkage=*/GlobalValue::InternalLinkage,
00879          /*Initializer=*/0, // has initializer, specified below
00880          /*Name=*/name(".str"),
00881          m_mod);
00882       globalFormat->setInitializer(format);
00883 
00884       Constant* const_int0 = Constant::getNullValue(IntegerType::get(32));
00885       std::vector<Constant*> const_ptr_21_indices;
00886       const_ptr_21_indices.push_back(const_int0);
00887       const_ptr_21_indices.push_back(const_int0);
00888       m_fmtPtr = ConstantExpr::getGetElementPtr(globalFormat,
00889                                                 &const_ptr_21_indices[0], const_ptr_21_indices.size());
00890    }
00891 
00892    Function *func_printf = m_mod->getFunction("printf");
00893    if (!func_printf)
00894       func_printf = declarePrintf();
00895    assert(func_printf);
00896    std::vector<llvm::Value*> vec = extractVector(val);
00897    Value *dx = m_builder.CreateFPExt(vec[0], Type::DoubleTy, name("dx"));
00898    Value *dy = m_builder.CreateFPExt(vec[1], Type::DoubleTy, name("dy"));
00899    Value *dz = m_builder.CreateFPExt(vec[2], Type::DoubleTy, name("dz"));
00900    Value *dw = m_builder.CreateFPExt(vec[3], Type::DoubleTy, name("dw"));
00901    std::vector<Value*> params;
00902    params.push_back(m_fmtPtr);
00903    params.push_back(dx);
00904    params.push_back(dy);
00905    params.push_back(dz);
00906    params.push_back(dw);
00907    CallInst *call = m_builder.CreateCall(func_printf, params.begin(), params.end(),
00908                                          name("printf"));
00909    call->setCallingConv(CallingConv::C);
00910    call->setTailCall(true);
00911 }
00912 
00913 const char * Instructions::name(const char *prefix)
00914 {
00915    ++m_idx;
00916    snprintf(m_name, 32, "%s%d", prefix, m_idx);
00917    return m_name;
00918 }
00919 
00920 llvm::Value * Instructions::callCeil(llvm::Value *val)
00921 {
00922    if (!m_llvmCeil) {
00923       // predeclare the intrinsic
00924       std::vector<const Type*> ceilArgs;
00925       ceilArgs.push_back(Type::FloatTy);
00926       AttrListPtr ceilPal;
00927       FunctionType* ceilType = FunctionType::get(
00928          /*Result=*/Type::FloatTy,
00929          /*Params=*/ceilArgs,
00930          /*isVarArg=*/false);
00931       m_llvmCeil = Function::Create(
00932          /*Type=*/ceilType,
00933          /*Linkage=*/GlobalValue::ExternalLinkage,
00934          /*Name=*/"ceilf", m_mod);
00935       m_llvmCeil->setCallingConv(CallingConv::C);
00936       m_llvmCeil->setAttributes(ceilPal);
00937    }
00938    CallInst *call =  m_builder.CreateCall(m_llvmCeil, val,
00939                                           name("ceilf"));
00940    call->setCallingConv(CallingConv::C);
00941    call->setTailCall(false);
00942    return call;
00943 }
00944 
00945 llvm::Value *Instructions::callFAbs(llvm::Value *val)
00946 {
00947    if (!m_llvmFAbs) {
00948       // predeclare the intrinsic
00949       std::vector<const Type*> fabsArgs;
00950       fabsArgs.push_back(Type::FloatTy);
00951       AttrListPtr fabsPal;
00952       FunctionType* fabsType = FunctionType::get(
00953          /*Result=*/Type::FloatTy,
00954          /*Params=*/fabsArgs,
00955          /*isVarArg=*/false);
00956       m_llvmFAbs = Function::Create(
00957          /*Type=*/fabsType,
00958          /*Linkage=*/GlobalValue::ExternalLinkage,
00959          /*Name=*/"fabs", m_mod);
00960       m_llvmFAbs->setCallingConv(CallingConv::C);
00961       m_llvmFAbs->setAttributes(fabsPal);
00962    }
00963    CallInst *call = m_builder.CreateCall(m_llvmFAbs, val,
00964                                          name("fabs"));
00965    call->setCallingConv(CallingConv::C);
00966    call->setTailCall(false);
00967    return call;
00968 }
00969 
00970 llvm::Value * Instructions::callFExp(llvm::Value *val)
00971 {
00972    if (!m_llvmFexp) {
00973       // predeclare the intrinsic
00974       std::vector<const Type*> fexpArgs;
00975       fexpArgs.push_back(Type::FloatTy);
00976       AttrListPtr fexpPal;
00977       FunctionType* fexpType = FunctionType::get(
00978          /*Result=*/Type::FloatTy,
00979          /*Params=*/fexpArgs,
00980          /*isVarArg=*/false);
00981       m_llvmFexp = Function::Create(
00982          /*Type=*/fexpType,
00983          /*Linkage=*/GlobalValue::ExternalLinkage,
00984          /*Name=*/"expf", m_mod);
00985       m_llvmFexp->setCallingConv(CallingConv::C);
00986       m_llvmFexp->setAttributes(fexpPal);
00987    }
00988    CallInst *call = m_builder.CreateCall(m_llvmFexp, val,
00989                                          name("expf"));
00990    call->setCallingConv(CallingConv::C);
00991    call->setTailCall(false);
00992    return call;
00993 }
00994 
00995 llvm::Value * Instructions::callFLog(llvm::Value *val)
00996 {
00997    if (!m_llvmFlog) {
00998       // predeclare the intrinsic
00999       std::vector<const Type*> flogArgs;
01000       flogArgs.push_back(Type::FloatTy);
01001       AttrListPtr flogPal;
01002       FunctionType* flogType = FunctionType::get(
01003          /*Result=*/Type::FloatTy,
01004          /*Params=*/flogArgs,
01005          /*isVarArg=*/false);
01006       m_llvmFlog = Function::Create(
01007          /*Type=*/flogType,
01008          /*Linkage=*/GlobalValue::ExternalLinkage,
01009          /*Name=*/"logf", m_mod);
01010       m_llvmFlog->setCallingConv(CallingConv::C);
01011       m_llvmFlog->setAttributes(flogPal);
01012    }
01013    CallInst *call = m_builder.CreateCall(m_llvmFlog, val,
01014                                          name("logf"));
01015    call->setCallingConv(CallingConv::C);
01016    call->setTailCall(false);
01017    return call;
01018 }
01019 
01020 llvm::Value * Instructions::callFloor(llvm::Value *val)
01021 {
01022    if (!m_llvmFloor) {
01023       // predeclare the intrinsic
01024       std::vector<const Type*> floorArgs;
01025       floorArgs.push_back(Type::FloatTy);
01026       AttrListPtr floorPal;
01027       FunctionType* floorType = FunctionType::get(
01028          /*Result=*/Type::FloatTy,
01029          /*Params=*/floorArgs,
01030          /*isVarArg=*/false);
01031       m_llvmFloor = Function::Create(
01032          /*Type=*/floorType,
01033          /*Linkage=*/GlobalValue::ExternalLinkage,
01034          /*Name=*/"floorf", m_mod);
01035       m_llvmFloor->setCallingConv(CallingConv::C);
01036       m_llvmFloor->setAttributes(floorPal);
01037    }
01038    CallInst *call =  m_builder.CreateCall(m_llvmFloor, val,
01039                                           name("floorf"));
01040    call->setCallingConv(CallingConv::C);
01041    call->setTailCall(false);
01042    return call;
01043 }
01044 
01045 llvm::Value *Instructions::callFSqrt(llvm::Value *val)
01046 {
01047    if (!m_llvmFSqrt) {
01048       // predeclare the intrinsic
01049       std::vector<const Type*> fsqrtArgs;
01050       fsqrtArgs.push_back(Type::FloatTy);
01051       AttrListPtr fsqrtPal;
01052       FunctionType* fsqrtType = FunctionType::get(
01053          /*Result=*/Type::FloatTy,
01054          /*Params=*/fsqrtArgs,
01055          /*isVarArg=*/false);
01056       m_llvmFSqrt = Function::Create(
01057          /*Type=*/fsqrtType,
01058          /*Linkage=*/GlobalValue::ExternalLinkage,
01059          /*Name=*/"llvm.sqrt.f32", m_mod);
01060       m_llvmFSqrt->setCallingConv(CallingConv::C);
01061       m_llvmFSqrt->setAttributes(fsqrtPal);
01062    }
01063    CallInst *call = m_builder.CreateCall(m_llvmFSqrt, val,
01064                                          name("sqrt"));
01065    call->setCallingConv(CallingConv::C);
01066    call->setTailCall(false);
01067    return call;
01068 }
01069 
01070 llvm::Value * Instructions::callPow(llvm::Value *val1, llvm::Value *val2)
01071 {
01072    if (!m_llvmPow) {
01073       // predeclare the intrinsic
01074       std::vector<const Type*> powArgs;
01075       powArgs.push_back(Type::FloatTy);
01076       powArgs.push_back(Type::FloatTy);
01077       AttrListPtr powPal;
01078       FunctionType* powType = FunctionType::get(
01079          /*Result=*/Type::FloatTy,
01080          /*Params=*/powArgs,
01081          /*isVarArg=*/false);
01082       m_llvmPow = Function::Create(
01083          /*Type=*/powType,
01084          /*Linkage=*/GlobalValue::ExternalLinkage,
01085          /*Name=*/"llvm.pow.f32", m_mod);
01086       m_llvmPow->setCallingConv(CallingConv::C);
01087       m_llvmPow->setAttributes(powPal);
01088    }
01089    std::vector<Value*> params;
01090    params.push_back(val1);
01091    params.push_back(val2);
01092    CallInst *call = m_builder.CreateCall(m_llvmPow, params.begin(), params.end(),
01093                                          name("pow"));
01094    call->setCallingConv(CallingConv::C);
01095    call->setTailCall(false);
01096    return call;
01097 }
01098 
01099 llvm::Value * Instructions::vectorFromVals(llvm::Value *x, llvm::Value *y,
01100                                            llvm::Value *z, llvm::Value *w)
01101 {
01102    Constant *const_vec = Constant::getNullValue(m_floatVecType);
01103    Value *res = m_builder.CreateInsertElement(const_vec, x,
01104                                               m_storage->constantInt(0),
01105                                               name("vecx"));
01106    res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1),
01107                                name("vecxy"));
01108    res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2),
01109                                name("vecxyz"));
01110    if (w)
01111       res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3),
01112                                           name("vecxyzw"));
01113    return res;
01114 }
01115 
01116 llvm::Value * Instructions::constVector(float x, float y, float z, float w)
01117 {
01118    std::vector<Constant*> vec(4);
01119    vec[0] = ConstantFP::get(APFloat(x));
01120    vec[1] = ConstantFP::get(APFloat(y));
01121    vec[2] = ConstantFP::get(APFloat(z));
01122    vec[3] = ConstantFP::get(APFloat(w));
01123    return ConstantVector::get(m_floatVecType, vec);
01124 }
01125 
01126 llvm::Function * Instructions::declarePrintf()
01127 {
01128    std::vector<const Type*> args;
01129    AttrListPtr params;
01130    FunctionType* funcTy = FunctionType::get(
01131       /*Result=*/IntegerType::get(32),
01132       /*Params=*/args,
01133       /*isVarArg=*/true);
01134    Function* func_printf = Function::Create(
01135       /*Type=*/funcTy,
01136       /*Linkage=*/GlobalValue::ExternalLinkage,
01137       /*Name=*/"printf", m_mod);
01138    func_printf->setCallingConv(CallingConv::C);
01139    func_printf->setAttributes(params);
01140    return func_printf;
01141 }
01142 
01143 llvm::Function * Instructions::declareFunc(int label)
01144 {
01145    PointerType *vecPtr = PointerType::getUnqual(m_floatVecType);
01146    std::vector<const Type*> args;
01147    args.push_back(vecPtr);
01148    args.push_back(vecPtr);
01149    args.push_back(vecPtr);
01150    args.push_back(vecPtr);
01151    AttrListPtr params;
01152    FunctionType *funcType = FunctionType::get(
01153       /*Result=*/Type::VoidTy,
01154       /*Params=*/args,
01155       /*isVarArg=*/false);
01156    std::string name = createFuncName(label);
01157    Function *func = Function::Create(
01158       /*Type=*/funcType,
01159       /*Linkage=*/GlobalValue::ExternalLinkage,
01160       /*Name=*/name.c_str(), m_mod);
01161    func->setCallingConv(CallingConv::C);
01162    func->setAttributes(params);
01163    return func;
01164 }
01165 
01166 llvm::Function * Instructions::findFunction(int label)
01167 {
01168    llvm::Function *func = m_functions[label];
01169    if (!func) {
01170       func = declareFunc(label);
01171       m_functions[label] = func;
01172    }
01173    return func;
01174 }
01175 
01176 std::vector<llvm::Value*> Instructions::extractVector(llvm::Value *vec)
01177 {
01178    std::vector<llvm::Value*> elems(4);
01179    elems[0] = m_builder.CreateExtractElement(vec, m_storage->constantInt(0),
01180                                              name("x"));
01181    elems[1] = m_builder.CreateExtractElement(vec, m_storage->constantInt(1),
01182                                              name("y"));
01183    elems[2] = m_builder.CreateExtractElement(vec, m_storage->constantInt(2),
01184                                              name("z"));
01185    elems[3] = m_builder.CreateExtractElement(vec, m_storage->constantInt(3),
01186                                              name("w"));
01187    return elems;
01188 }
01189 
01190 
01191 #endif //MESA_LLVM
01192 
01193 

Generated on Tue Sep 29 06:25:14 2009 for Gallium3D by  doxygen 1.5.4