00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
00302 assert(0);
00303 }
00304
00305 llvm::Value * Instructions::ddy(llvm::Value *in)
00306 {
00307
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
00477
00478
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
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 arrayTy,
00877 true,
00878 GlobalValue::InternalLinkage,
00879 0,
00880 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
00924 std::vector<const Type*> ceilArgs;
00925 ceilArgs.push_back(Type::FloatTy);
00926 AttrListPtr ceilPal;
00927 FunctionType* ceilType = FunctionType::get(
00928 Type::FloatTy,
00929 ceilArgs,
00930 false);
00931 m_llvmCeil = Function::Create(
00932 ceilType,
00933 GlobalValue::ExternalLinkage,
00934 "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
00949 std::vector<const Type*> fabsArgs;
00950 fabsArgs.push_back(Type::FloatTy);
00951 AttrListPtr fabsPal;
00952 FunctionType* fabsType = FunctionType::get(
00953 Type::FloatTy,
00954 fabsArgs,
00955 false);
00956 m_llvmFAbs = Function::Create(
00957 fabsType,
00958 GlobalValue::ExternalLinkage,
00959 "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
00974 std::vector<const Type*> fexpArgs;
00975 fexpArgs.push_back(Type::FloatTy);
00976 AttrListPtr fexpPal;
00977 FunctionType* fexpType = FunctionType::get(
00978 Type::FloatTy,
00979 fexpArgs,
00980 false);
00981 m_llvmFexp = Function::Create(
00982 fexpType,
00983 GlobalValue::ExternalLinkage,
00984 "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
00999 std::vector<const Type*> flogArgs;
01000 flogArgs.push_back(Type::FloatTy);
01001 AttrListPtr flogPal;
01002 FunctionType* flogType = FunctionType::get(
01003 Type::FloatTy,
01004 flogArgs,
01005 false);
01006 m_llvmFlog = Function::Create(
01007 flogType,
01008 GlobalValue::ExternalLinkage,
01009 "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
01024 std::vector<const Type*> floorArgs;
01025 floorArgs.push_back(Type::FloatTy);
01026 AttrListPtr floorPal;
01027 FunctionType* floorType = FunctionType::get(
01028 Type::FloatTy,
01029 floorArgs,
01030 false);
01031 m_llvmFloor = Function::Create(
01032 floorType,
01033 GlobalValue::ExternalLinkage,
01034 "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
01049 std::vector<const Type*> fsqrtArgs;
01050 fsqrtArgs.push_back(Type::FloatTy);
01051 AttrListPtr fsqrtPal;
01052 FunctionType* fsqrtType = FunctionType::get(
01053 Type::FloatTy,
01054 fsqrtArgs,
01055 false);
01056 m_llvmFSqrt = Function::Create(
01057 fsqrtType,
01058 GlobalValue::ExternalLinkage,
01059 "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
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 Type::FloatTy,
01080 powArgs,
01081 false);
01082 m_llvmPow = Function::Create(
01083 powType,
01084 GlobalValue::ExternalLinkage,
01085 "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 IntegerType::get(32),
01132 args,
01133 true);
01134 Function* func_printf = Function::Create(
01135 funcTy,
01136 GlobalValue::ExternalLinkage,
01137 "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 Type::VoidTy,
01154 args,
01155 false);
01156 std::string name = createFuncName(label);
01157 Function *func = Function::Create(
01158 funcType,
01159 GlobalValue::ExternalLinkage,
01160 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