Clone of mesa.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

instructions.cpp 42KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193
  1. /**************************************************************************
  2. *
  3. * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  4. * All Rights Reserved.
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a
  7. * copy of this software and associated documentation files (the
  8. * "Software"), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish,
  10. * distribute, sub license, and/or sell copies of the Software, and to
  11. * permit persons to whom the Software is furnished to do so, subject to
  12. * the following conditions:
  13. *
  14. * The above copyright notice and this permission notice (including the
  15. * next paragraph) shall be included in all copies or substantial portions
  16. * of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21. * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  22. * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25. *
  26. **************************************************************************/
  27. /*
  28. * Authors:
  29. * Zack Rusin zack@tungstengraphics.com
  30. */
  31. #ifdef MESA_LLVM
  32. #include "instructions.h"
  33. #include "storage.h"
  34. #include "util/u_memory.h"
  35. #include <llvm/CallingConv.h>
  36. #include <llvm/Constants.h>
  37. #include <llvm/DerivedTypes.h>
  38. #include <llvm/Function.h>
  39. #include <llvm/InstrTypes.h>
  40. #include <llvm/Instructions.h>
  41. #include <llvm/ParameterAttributes.h>
  42. #include <llvm/Support/MemoryBuffer.h>
  43. #include <llvm/Bitcode/ReaderWriter.h>
  44. #include <sstream>
  45. #include <fstream>
  46. #include <iostream>
  47. using namespace llvm;
  48. #include "gallivm_builtins.cpp"
  49. #if 0
  50. llvm::Value *arrayFromChannels(std::vector<llvm::Value*> &vals)
  51. {
  52. VectorType *vectorType = VectorType::get(Type::FloatTy, 4);
  53. ArrayType *vectorArray = ArrayType::get(vectorType, 4);
  54. }
  55. #endif
  56. static inline std::string createFuncName(int label)
  57. {
  58. std::ostringstream stream;
  59. stream << "function";
  60. stream << label;
  61. return stream.str();
  62. }
  63. Instructions::Instructions(llvm::Module *mod, llvm::Function *func, llvm::BasicBlock *block,
  64. Storage *storage)
  65. : m_mod(mod), m_func(func), m_builder(block), m_idx(0),
  66. m_storage(storage)
  67. {
  68. m_floatVecType = VectorType::get(Type::FloatTy, 4);
  69. m_llvmFSqrt = 0;
  70. m_llvmFAbs = 0;
  71. m_llvmPow = 0;
  72. m_llvmFloor = 0;
  73. m_llvmFlog = 0;
  74. m_llvmFexp = 0;
  75. m_llvmLit = 0;
  76. m_fmtPtr = 0;
  77. MemoryBuffer *buffer = MemoryBuffer::getMemBuffer(
  78. (const char*)&llvm_builtins_data[0],
  79. (const char*)&llvm_builtins_data[Elements(llvm_builtins_data)-1]);
  80. m_mod = ParseBitcodeFile(buffer);
  81. }
  82. llvm::BasicBlock * Instructions::currentBlock() const
  83. {
  84. return m_builder.GetInsertBlock();
  85. }
  86. llvm::Value * Instructions::abs(llvm::Value *in)
  87. {
  88. std::vector<llvm::Value*> vec = extractVector(in);
  89. Value *xabs = callFAbs(vec[0]);
  90. Value *yabs = callFAbs(vec[1]);
  91. Value *zabs = callFAbs(vec[2]);
  92. Value *wabs = callFAbs(vec[3]);
  93. return vectorFromVals(xabs, yabs, zabs, wabs);
  94. }
  95. llvm::Value * Instructions::add(llvm::Value *in1, llvm::Value *in2)
  96. {
  97. return m_builder.CreateAdd(in1, in2, name("add"));
  98. }
  99. llvm::Value * Instructions::arl(llvm::Value *in)
  100. {
  101. return floor(in);
  102. }
  103. void Instructions::beginLoop()
  104. {
  105. BasicBlock *begin = BasicBlock::Create(name("loop"), m_func,0);
  106. BasicBlock *end = BasicBlock::Create(name("endloop"), m_func,0);
  107. m_builder.CreateBr(begin);
  108. Loop loop;
  109. loop.begin = begin;
  110. loop.end = end;
  111. m_builder.SetInsertPoint(begin);
  112. m_loopStack.push(loop);
  113. }
  114. void Instructions::bgnSub(unsigned label)
  115. {
  116. llvm::Function *func = findFunction(label);
  117. Function::arg_iterator args = func->arg_begin();
  118. Value *ptr_INPUT = args++;
  119. ptr_INPUT->setName("INPUT");
  120. m_storage->pushArguments(ptr_INPUT);
  121. llvm::BasicBlock *entry = BasicBlock::Create("entry", func, 0);
  122. m_func = func;
  123. m_builder.SetInsertPoint(entry);
  124. }
  125. void Instructions::brk()
  126. {
  127. assert(!m_loopStack.empty());
  128. BasicBlock *unr = BasicBlock::Create(name("unreachable"), m_func,0);
  129. m_builder.CreateBr(m_loopStack.top().end);
  130. m_builder.SetInsertPoint(unr);
  131. }
  132. void Instructions::cal(int label, llvm::Value *input)
  133. {
  134. std::vector<Value*> params;
  135. params.push_back(input);
  136. llvm::Function *func = findFunction(label);
  137. m_builder.CreateCall(func, params.begin(), params.end());
  138. }
  139. llvm::Value * Instructions::ceil(llvm::Value *in)
  140. {
  141. std::vector<llvm::Value*> vec = extractVector(in);
  142. return vectorFromVals(callCeil(vec[0]), callCeil(vec[1]),
  143. callCeil(vec[2]), callCeil(vec[3]));
  144. }
  145. llvm::Value * Instructions::clamp(llvm::Value *in1)
  146. {
  147. llvm::Value *zero = constVector(0.0f, 0.0f, 0.0f, 0.0f);
  148. llvm::Value *one = constVector(1.0f, 1.0f, 1.0f, 1.0f);
  149. return min( max(zero, in1), one);
  150. }
  151. llvm::Value * Instructions::cmp(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3)
  152. {
  153. llvm::Function *func = m_mod->getFunction("cmp");
  154. assert(func);
  155. std::vector<Value*> params;
  156. params.push_back(in1);
  157. params.push_back(in2);
  158. params.push_back(in3);
  159. CallInst *call = m_builder.CreateCall(func, params.begin(), params.end(), name("cmpres"));
  160. call->setTailCall(false);
  161. return call;
  162. }
  163. llvm::Value * Instructions::cnd(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3)
  164. {
  165. std::vector<llvm::Value*> vec1 = extractVector(in1);
  166. std::vector<llvm::Value*> vec2 = extractVector(in2);
  167. std::vector<llvm::Value*> vec3 = extractVector(in3);
  168. Constant *half = ConstantFP::get(APFloat(0.5f));
  169. Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], half, name("xcmp"));
  170. Value *selx = m_builder.CreateSelect(xcmp, vec2[0], vec3[0],
  171. name("selx"));
  172. Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], half, name("ycmp"));
  173. Value *sely = m_builder.CreateSelect(ycmp, vec2[1], vec3[1],
  174. name("sely"));
  175. Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], half, name("zcmp"));
  176. Value *selz = m_builder.CreateSelect(zcmp, vec2[2], vec3[2],
  177. name("selz"));
  178. Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], half, name("wcmp"));
  179. Value *selw = m_builder.CreateSelect(wcmp, vec2[3], vec3[3],
  180. name("selw"));
  181. return vectorFromVals(selx, sely, selz, selw);
  182. }
  183. llvm::Value * Instructions::cnd0(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3)
  184. {
  185. std::vector<llvm::Value*> vec1 = extractVector(in1);
  186. std::vector<llvm::Value*> vec2 = extractVector(in2);
  187. std::vector<llvm::Value*> vec3 = extractVector(in3);
  188. Constant *zero = Constant::getNullValue(Type::FloatTy);
  189. Value *xcmp = m_builder.CreateFCmpOGE(vec1[0], zero, name("xcmp"));
  190. Value *selx = m_builder.CreateSelect(xcmp, vec2[0], vec3[0],
  191. name("selx"));
  192. Value *ycmp = m_builder.CreateFCmpOGE(vec1[1], zero, name("ycmp"));
  193. Value *sely = m_builder.CreateSelect(ycmp, vec2[1], vec3[1],
  194. name("sely"));
  195. Value *zcmp = m_builder.CreateFCmpOGE(vec1[2], zero, name("zcmp"));
  196. Value *selz = m_builder.CreateSelect(zcmp, vec2[2], vec3[2],
  197. name("selz"));
  198. Value *wcmp = m_builder.CreateFCmpOGE(vec1[3], zero, name("wcmp"));
  199. Value *selw = m_builder.CreateSelect(wcmp, vec2[3], vec3[3],
  200. name("selw"));
  201. return vectorFromVals(selx, sely, selz, selw);
  202. }
  203. llvm::Value * Instructions::cos(llvm::Value *in)
  204. {
  205. #if 0
  206. llvm::Function *func = m_mod->getFunction("vcos");
  207. assert(func);
  208. CallInst *call = m_builder.CreateCall(func, in, name("cosres"));
  209. call->setTailCall(false);
  210. return call;
  211. #else
  212. std::vector<llvm::Value*> elems = extractVector(in);
  213. Function *func = m_mod->getFunction("cosf");
  214. assert(func);
  215. CallInst *cos = m_builder.CreateCall(func, elems[0], name("cosres"));
  216. cos->setCallingConv(CallingConv::C);
  217. cos->setTailCall(true);
  218. return vectorFromVals(cos, cos, cos, cos);
  219. #endif
  220. }
  221. llvm::Value * Instructions::cross(llvm::Value *in1, llvm::Value *in2)
  222. {
  223. Value *x1 = m_builder.CreateExtractElement(in1,
  224. m_storage->constantInt(0),
  225. name("x1"));
  226. Value *y1 = m_builder.CreateExtractElement(in1,
  227. m_storage->constantInt(1),
  228. name("y1"));
  229. Value *z1 = m_builder.CreateExtractElement(in1,
  230. m_storage->constantInt(2),
  231. name("z1"));
  232. Value *x2 = m_builder.CreateExtractElement(in2,
  233. m_storage->constantInt(0),
  234. name("x2"));
  235. Value *y2 = m_builder.CreateExtractElement(in2,
  236. m_storage->constantInt(1),
  237. name("y2"));
  238. Value *z2 = m_builder.CreateExtractElement(in2,
  239. m_storage->constantInt(2),
  240. name("z2"));
  241. Value *y1z2 = mul(y1, z2);
  242. Value *z1y2 = mul(z1, y2);
  243. Value *z1x2 = mul(z1, x2);
  244. Value *x1z2 = mul(x1, z2);
  245. Value *x1y2 = mul(x1, y2);
  246. Value *y1x2 = mul(y1, x2);
  247. return vectorFromVals(sub(y1z2, z1y2), sub(z1x2, x1z2), sub(x1y2, y1x2));
  248. }
  249. llvm::Value * Instructions::ddx(llvm::Value *in)
  250. {
  251. // FIXME
  252. assert(0);
  253. }
  254. llvm::Value * Instructions::ddy(llvm::Value *in)
  255. {
  256. // FIXME
  257. assert(0);
  258. }
  259. llvm::Value * Instructions::div(llvm::Value *in1, llvm::Value *in2)
  260. {
  261. return m_builder.CreateFDiv(in1, in2, name("div"));
  262. }
  263. llvm::Value * Instructions::dot2add(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3)
  264. {
  265. Value *mulRes = mul(in1, in2);
  266. Value *x = m_builder.CreateExtractElement(mulRes,
  267. m_storage->constantInt(0),
  268. name("extractx"));
  269. Value *y = m_builder.CreateExtractElement(mulRes,
  270. m_storage->constantInt(1),
  271. name("extracty"));
  272. Value *z = m_builder.CreateExtractElement(in3,
  273. m_storage->constantInt(2),
  274. name("extractz"));
  275. Value *xy = m_builder.CreateAdd(x, y,name("xy"));
  276. Value *dot2add = m_builder.CreateAdd(xy, z, name("dot2add"));
  277. return vectorFromVals(dot2add, dot2add, dot2add, dot2add);
  278. }
  279. llvm::Value * Instructions::dp2(llvm::Value *in1, llvm::Value *in2)
  280. {
  281. Value *mulRes = mul(in1, in2);
  282. Value *x = m_builder.CreateExtractElement(mulRes,
  283. m_storage->constantInt(0),
  284. name("extractx"));
  285. Value *y = m_builder.CreateExtractElement(mulRes,
  286. m_storage->constantInt(1),
  287. name("extracty"));
  288. Value *xy = m_builder.CreateAdd(x, y,name("xy"));
  289. return vectorFromVals(xy, xy, xy, xy);
  290. }
  291. llvm::Value * Instructions::dp3(llvm::Value *in1, llvm::Value *in2)
  292. {
  293. Value *mulRes = mul(in1, in2);
  294. Value *x = m_builder.CreateExtractElement(mulRes,
  295. m_storage->constantInt(0),
  296. name("extractx"));
  297. Value *y = m_builder.CreateExtractElement(mulRes,
  298. m_storage->constantInt(1),
  299. name("extracty"));
  300. Value *z = m_builder.CreateExtractElement(mulRes,
  301. m_storage->constantInt(2),
  302. name("extractz"));
  303. Value *xy = m_builder.CreateAdd(x, y,name("xy"));
  304. Value *dot3 = m_builder.CreateAdd(xy, z, name("dot3"));
  305. return vectorFromVals(dot3, dot3, dot3, dot3);
  306. }
  307. llvm::Value * Instructions::dp4(llvm::Value *in1, llvm::Value *in2)
  308. {
  309. Value *mulRes = mul(in1, in2);
  310. std::vector<llvm::Value*> vec = extractVector(mulRes);
  311. Value *xy = m_builder.CreateAdd(vec[0], vec[1], name("xy"));
  312. Value *xyz = m_builder.CreateAdd(xy, vec[2], name("xyz"));
  313. Value *dot4 = m_builder.CreateAdd(xyz, vec[3], name("dot4"));
  314. return vectorFromVals(dot4, dot4, dot4, dot4);
  315. }
  316. llvm::Value * Instructions::dph(llvm::Value *in1, llvm::Value *in2)
  317. {
  318. Value *mulRes = mul(in1, in2);
  319. std::vector<llvm::Value*> vec1 = extractVector(mulRes);
  320. Value *xy = m_builder.CreateAdd(vec1[0], vec1[1], name("xy"));
  321. Value *xyz = m_builder.CreateAdd(xy, vec1[2], name("xyz"));
  322. Value *dph = m_builder.CreateAdd(xyz, vec1[3], name("dph"));
  323. return vectorFromVals(dph, dph, dph, dph);
  324. }
  325. llvm::Value * Instructions::dst(llvm::Value *in1, llvm::Value *in2)
  326. {
  327. Value *y1 = m_builder.CreateExtractElement(in1,
  328. m_storage->constantInt(1),
  329. name("y1"));
  330. Value *z = m_builder.CreateExtractElement(in1,
  331. m_storage->constantInt(2),
  332. name("z"));
  333. Value *y2 = m_builder.CreateExtractElement(in2,
  334. m_storage->constantInt(1),
  335. name("y2"));
  336. Value *w = m_builder.CreateExtractElement(in2,
  337. m_storage->constantInt(3),
  338. name("w"));
  339. Value *ry = m_builder.CreateMul(y1, y2, name("tyuy"));
  340. return vectorFromVals(ConstantFP::get(APFloat(1.f)),
  341. ry, z, w);
  342. }
  343. void Instructions::elseop()
  344. {
  345. assert(!m_ifStack.empty());
  346. BasicBlock *ifend = BasicBlock::Create(name("ifend"), m_func,0);
  347. m_builder.CreateBr(ifend);
  348. m_builder.SetInsertPoint(m_ifStack.top());
  349. currentBlock()->setName(name("ifelse"));
  350. m_ifStack.pop();
  351. m_ifStack.push(ifend);
  352. }
  353. void Instructions::endif()
  354. {
  355. assert(!m_ifStack.empty());
  356. m_builder.CreateBr(m_ifStack.top());
  357. m_builder.SetInsertPoint(m_ifStack.top());
  358. m_ifStack.pop();
  359. }
  360. void Instructions::endLoop()
  361. {
  362. assert(!m_loopStack.empty());
  363. Loop loop = m_loopStack.top();
  364. m_builder.CreateBr(loop.begin);
  365. loop.end->moveAfter(currentBlock());
  366. m_builder.SetInsertPoint(loop.end);
  367. m_loopStack.pop();
  368. }
  369. void Instructions::end()
  370. {
  371. m_builder.CreateRetVoid();
  372. }
  373. void Instructions::endSub()
  374. {
  375. m_func = 0;
  376. m_builder.SetInsertPoint(0);
  377. }
  378. llvm::Value * Instructions::exp(llvm::Value *in)
  379. {
  380. std::vector<llvm::Value*> vec = extractVector(in);
  381. return vectorFromVals(callFExp(vec[0]), callFExp(vec[1]),
  382. callFExp(vec[2]), callFExp(vec[3]));
  383. }
  384. llvm::Value * Instructions::ex2(llvm::Value *in)
  385. {
  386. llvm::Value *val = callPow(ConstantFP::get(APFloat(2.f)),
  387. m_builder.CreateExtractElement(
  388. in, m_storage->constantInt(0),
  389. name("x1")));
  390. return vectorFromVals(val, val, val, val);
  391. }
  392. llvm::Value * Instructions::floor(llvm::Value *in)
  393. {
  394. std::vector<llvm::Value*> vec = extractVector(in);
  395. return vectorFromVals(callFloor(vec[0]), callFloor(vec[1]),
  396. callFloor(vec[2]), callFloor(vec[3]));
  397. }
  398. llvm::Value * Instructions::frc(llvm::Value *in)
  399. {
  400. llvm::Value *flr = floor(in);
  401. return sub(in, flr);
  402. }
  403. void Instructions::ifop(llvm::Value *in)
  404. {
  405. BasicBlock *ifthen = BasicBlock::Create(name("ifthen"), m_func,0);
  406. BasicBlock *ifend = BasicBlock::Create(name("ifthenend"), m_func,0);
  407. //BasicBlock *yblock = new BasicBlock(name("yblock"), m_func,0);
  408. //BasicBlock *zblock = new BasicBlock(name("zblock"), m_func,0);
  409. //BasicBlock *wblock = new BasicBlock(name("wblock"), m_func,0);
  410. Constant *float0 = Constant::getNullValue(Type::FloatTy);
  411. Value *x = m_builder.CreateExtractElement(in, m_storage->constantInt(0),
  412. name("extractx"));
  413. Value *xcmp = m_builder.CreateFCmpUNE(x, float0, name("xcmp"));
  414. m_builder.CreateCondBr(xcmp, ifthen, ifend);
  415. //m_builder.SetInsertPoint(yblock);
  416. m_builder.SetInsertPoint(ifthen);
  417. m_ifStack.push(ifend);
  418. }
  419. llvm::Value * Instructions::kil(llvm::Value *in)
  420. {
  421. llvm::Function *func = m_mod->getFunction("kil");
  422. assert(func);
  423. CallInst *call = m_builder.CreateCall(func, in, name("kilpres"));
  424. call->setTailCall(false);
  425. return call;
  426. }
  427. llvm::Value * Instructions::lerp(llvm::Value *in1, llvm::Value *in2,
  428. llvm::Value *in3)
  429. {
  430. llvm::Value *m = mul(in1, in2);
  431. llvm::Value *vec1 = constVector(1.f, 1.f, 1.f, 1.f);
  432. llvm::Value *s = sub(vec1, in1);
  433. return add(m, mul(s, in3));
  434. }
  435. llvm::Value * Instructions::lg2(llvm::Value *in)
  436. {
  437. std::vector<llvm::Value*> vec = extractVector(in);
  438. llvm::Value *const_vec = constVector(1.442695f, 1.442695f,
  439. 1.442695f, 1.442695f);
  440. return mul(vectorFromVals(callFLog(vec[0]), callFLog(vec[1]),
  441. callFLog(vec[2]), callFLog(vec[3])), const_vec);
  442. }
  443. llvm::Value * Instructions::lit(llvm::Value *in)
  444. {
  445. if (!m_llvmLit) {
  446. m_llvmLit = m_mod->getFunction("lit");
  447. }
  448. CallInst *call = m_builder.CreateCall(m_llvmLit, in, name("litres"));
  449. call->setCallingConv(CallingConv::C);
  450. call->setTailCall(false);
  451. return call;
  452. }
  453. llvm::Value * Instructions::log(llvm::Value *in)
  454. {
  455. std::vector<llvm::Value*> vec = extractVector(in);
  456. return vectorFromVals(callFLog(vec[0]), callFLog(vec[1]),
  457. callFLog(vec[2]), callFLog(vec[3]));
  458. }
  459. llvm::Value * Instructions::madd(llvm::Value *in1, llvm::Value *in2,
  460. llvm::Value *in3)
  461. {
  462. Value *mulRes = mul(in1, in2);
  463. return add(mulRes, in3);
  464. }
  465. llvm::Value * Instructions::max(llvm::Value *in1, llvm::Value *in2)
  466. {
  467. std::vector<llvm::Value*> vec1 = extractVector(in1);
  468. std::vector<llvm::Value*> vec2 = extractVector(in2);
  469. Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0],
  470. name("xcmp"));
  471. Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0],
  472. name("selx"));
  473. Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1],
  474. name("ycmp"));
  475. Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1],
  476. name("sely"));
  477. Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2],
  478. name("zcmp"));
  479. Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2],
  480. name("selz"));
  481. Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3],
  482. name("wcmp"));
  483. Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3],
  484. name("selw"));
  485. return vectorFromVals(selx, sely, selz, selw);
  486. }
  487. llvm::Value * Instructions::min(llvm::Value *in1, llvm::Value *in2)
  488. {
  489. std::vector<llvm::Value*> vec1 = extractVector(in1);
  490. std::vector<llvm::Value*> vec2 = extractVector(in2);
  491. Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp"));
  492. Value *selx = m_builder.CreateSelect(xcmp, vec1[0], vec2[0],
  493. name("selx"));
  494. Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp"));
  495. Value *sely = m_builder.CreateSelect(ycmp, vec1[1], vec2[1],
  496. name("sely"));
  497. Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp"));
  498. Value *selz = m_builder.CreateSelect(zcmp, vec1[2], vec2[2],
  499. name("selz"));
  500. Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp"));
  501. Value *selw = m_builder.CreateSelect(wcmp, vec1[3], vec2[3],
  502. name("selw"));
  503. return vectorFromVals(selx, sely, selz, selw);
  504. }
  505. llvm::Value * Instructions::mul(llvm::Value *in1, llvm::Value *in2)
  506. {
  507. return m_builder.CreateMul(in1, in2, name("mul"));
  508. }
  509. llvm::Value * Instructions::neg(llvm::Value *in)
  510. {
  511. Value *neg = m_builder.CreateNeg(in, name("neg"));
  512. return neg;
  513. }
  514. llvm::Value * Instructions::nrm(llvm::Value *in)
  515. {
  516. llvm::Value *v = rsq(in);
  517. return mul(v, in);
  518. }
  519. llvm::Value * Instructions::pow(llvm::Value *in1, llvm::Value *in2)
  520. {
  521. Value *x1 = m_builder.CreateExtractElement(in1,
  522. m_storage->constantInt(0),
  523. name("x1"));
  524. Value *x2 = m_builder.CreateExtractElement(in2,
  525. m_storage->constantInt(0),
  526. name("x2"));
  527. llvm::Value *val = callPow(x1, x2);
  528. return vectorFromVals(val, val, val, val);
  529. }
  530. llvm::Value * Instructions::rcp(llvm::Value *in1)
  531. {
  532. Value *x1 = m_builder.CreateExtractElement(in1,
  533. m_storage->constantInt(0),
  534. name("x1"));
  535. Value *res = m_builder.CreateFDiv(ConstantFP::get(APFloat(1.f)),
  536. x1, name("rcp"));
  537. return vectorFromVals(res, res, res, res);
  538. }
  539. llvm::Value * Instructions::rsq(llvm::Value *in1)
  540. {
  541. Value *x = m_builder.CreateExtractElement(in1,
  542. m_storage->constantInt(0),
  543. name("extractx"));
  544. Value *abs = callFAbs(x);
  545. Value *sqrt = callFSqrt(abs);
  546. Value *rsqrt = m_builder.CreateFDiv(ConstantFP::get(APFloat(1.f)),
  547. sqrt,
  548. name("rsqrt"));
  549. return vectorFromVals(rsqrt, rsqrt, rsqrt, rsqrt);
  550. }
  551. llvm::Value * Instructions::scs(llvm::Value *in)
  552. {
  553. llvm::Function *func = m_mod->getFunction("scs");
  554. assert(func);
  555. CallInst *call = m_builder.CreateCall(func, in, name("scsres"));
  556. call->setTailCall(false);
  557. return call;
  558. }
  559. llvm::Value * Instructions::seq(llvm::Value *in1, llvm::Value *in2)
  560. {
  561. Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
  562. Constant *const0f = Constant::getNullValue(Type::FloatTy);
  563. std::vector<llvm::Value*> vec1 = extractVector(in1);
  564. std::vector<llvm::Value*> vec2 = extractVector(in2);
  565. Value *xcmp = m_builder.CreateFCmpOEQ(vec1[0], vec2[0], name("xcmp"));
  566. Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
  567. Value *ycmp = m_builder.CreateFCmpOEQ(vec1[1], vec2[1], name("ycmp"));
  568. Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
  569. Value *zcmp = m_builder.CreateFCmpOEQ(vec1[2], vec2[2], name("zcmp"));
  570. Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
  571. Value *wcmp = m_builder.CreateFCmpOEQ(vec1[3], vec2[3], name("wcmp"));
  572. Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
  573. return vectorFromVals(x, y, z, w);
  574. }
  575. llvm::Value * Instructions::sfl(llvm::Value *in1, llvm::Value *in2)
  576. {
  577. Constant *const0f = Constant::getNullValue(Type::FloatTy);
  578. return vectorFromVals(const0f, const0f, const0f, const0f);
  579. }
  580. llvm::Value * Instructions::sge(llvm::Value *in1, llvm::Value *in2)
  581. {
  582. Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
  583. Constant *const0f = Constant::getNullValue(Type::FloatTy);
  584. std::vector<llvm::Value*> vec1 = extractVector(in1);
  585. std::vector<llvm::Value*> vec2 = extractVector(in2);
  586. Value *xcmp = m_builder.CreateFCmpOGE(vec1[0], vec2[0], name("xcmp"));
  587. Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
  588. Value *ycmp = m_builder.CreateFCmpOGE(vec1[1], vec2[1], name("ycmp"));
  589. Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
  590. Value *zcmp = m_builder.CreateFCmpOGE(vec1[2], vec2[2], name("zcmp"));
  591. Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
  592. Value *wcmp = m_builder.CreateFCmpOGE(vec1[3], vec2[3], name("wcmp"));
  593. Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
  594. return vectorFromVals(x, y, z, w);
  595. }
  596. llvm::Value * Instructions::sgt(llvm::Value *in1, llvm::Value *in2)
  597. {
  598. Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
  599. Constant *const0f = Constant::getNullValue(Type::FloatTy);
  600. std::vector<llvm::Value*> vec1 = extractVector(in1);
  601. std::vector<llvm::Value*> vec2 = extractVector(in2);
  602. Value *xcmp = m_builder.CreateFCmpOGT(vec1[0], vec2[0], name("xcmp"));
  603. Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
  604. Value *ycmp = m_builder.CreateFCmpOGT(vec1[1], vec2[1], name("ycmp"));
  605. Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
  606. Value *zcmp = m_builder.CreateFCmpOGT(vec1[2], vec2[2], name("zcmp"));
  607. Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
  608. Value *wcmp = m_builder.CreateFCmpOGT(vec1[3], vec2[3], name("wcmp"));
  609. Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
  610. return vectorFromVals(x, y, z, w);
  611. }
  612. llvm::Value * Instructions::sin(llvm::Value *in)
  613. {
  614. llvm::Function *func = m_mod->getFunction("vsin");
  615. assert(func);
  616. CallInst *call = m_builder.CreateCall(func, in, name("sinres"));
  617. call->setTailCall(false);
  618. return call;
  619. }
  620. llvm::Value * Instructions::sle(llvm::Value *in1, llvm::Value *in2)
  621. {
  622. Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
  623. Constant *const0f = Constant::getNullValue(Type::FloatTy);
  624. std::vector<llvm::Value*> vec1 = extractVector(in1);
  625. std::vector<llvm::Value*> vec2 = extractVector(in2);
  626. Value *xcmp = m_builder.CreateFCmpOLE(vec1[0], vec2[0], name("xcmp"));
  627. Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
  628. Value *ycmp = m_builder.CreateFCmpOLE(vec1[1], vec2[1], name("ycmp"));
  629. Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
  630. Value *zcmp = m_builder.CreateFCmpOLE(vec1[2], vec2[2], name("zcmp"));
  631. Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
  632. Value *wcmp = m_builder.CreateFCmpOLE(vec1[3], vec2[3], name("wcmp"));
  633. Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
  634. return vectorFromVals(x, y, z, w);
  635. }
  636. llvm::Value * Instructions::slt(llvm::Value *in1, llvm::Value *in2)
  637. {
  638. Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
  639. Constant *const0f = Constant::getNullValue(Type::FloatTy);
  640. std::vector<llvm::Value*> vec1 = extractVector(in1);
  641. std::vector<llvm::Value*> vec2 = extractVector(in2);
  642. Value *xcmp = m_builder.CreateFCmpOLT(vec1[0], vec2[0], name("xcmp"));
  643. Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
  644. Value *ycmp = m_builder.CreateFCmpOLT(vec1[1], vec2[1], name("ycmp"));
  645. Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
  646. Value *zcmp = m_builder.CreateFCmpOLT(vec1[2], vec2[2], name("zcmp"));
  647. Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
  648. Value *wcmp = m_builder.CreateFCmpOLT(vec1[3], vec2[3], name("wcmp"));
  649. Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
  650. return vectorFromVals(x, y, z, w);
  651. }
  652. llvm::Value * Instructions::sne(llvm::Value *in1, llvm::Value *in2)
  653. {
  654. Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
  655. Constant *const0f = Constant::getNullValue(Type::FloatTy);
  656. std::vector<llvm::Value*> vec1 = extractVector(in1);
  657. std::vector<llvm::Value*> vec2 = extractVector(in2);
  658. Value *xcmp = m_builder.CreateFCmpONE(vec1[0], vec2[0], name("xcmp"));
  659. Value *x = m_builder.CreateSelect(xcmp, const1f, const0f, name("xsel"));
  660. Value *ycmp = m_builder.CreateFCmpONE(vec1[1], vec2[1], name("ycmp"));
  661. Value *y = m_builder.CreateSelect(ycmp, const1f, const0f, name("ysel"));
  662. Value *zcmp = m_builder.CreateFCmpONE(vec1[2], vec2[2], name("zcmp"));
  663. Value *z = m_builder.CreateSelect(zcmp, const1f, const0f, name("zsel"));
  664. Value *wcmp = m_builder.CreateFCmpONE(vec1[3], vec2[3], name("wcmp"));
  665. Value *w = m_builder.CreateSelect(wcmp, const1f, const0f, name("wsel"));
  666. return vectorFromVals(x, y, z, w);
  667. }
  668. llvm::Value * Instructions::str(llvm::Value *in1, llvm::Value *in2)
  669. {
  670. Constant *const1f = ConstantFP::get(APFloat(1.000000e+00f));
  671. return vectorFromVals(const1f, const1f, const1f, const1f);
  672. }
  673. llvm::Value * Instructions::sub(llvm::Value *in1, llvm::Value *in2)
  674. {
  675. Value *res = m_builder.CreateSub(in1, in2, name("sub"));
  676. return res;
  677. }
  678. llvm::Value * Instructions::trunc(llvm::Value *in)
  679. {
  680. std::vector<llvm::Value*> vec = extractVector(in);
  681. Value *icastx = m_builder.CreateFPToSI(vec[0], IntegerType::get(32),
  682. name("ftoix"));
  683. Value *icasty = m_builder.CreateFPToSI(vec[1], IntegerType::get(32),
  684. name("ftoiy"));
  685. Value *icastz = m_builder.CreateFPToSI(vec[2], IntegerType::get(32),
  686. name("ftoiz"));
  687. Value *icastw = m_builder.CreateFPToSI(vec[3], IntegerType::get(32),
  688. name("ftoiw"));
  689. Value *fx = m_builder.CreateSIToFP(icastx, Type::FloatTy,
  690. name("fx"));
  691. Value *fy = m_builder.CreateSIToFP(icasty, Type::FloatTy,
  692. name("fy"));
  693. Value *fz = m_builder.CreateSIToFP(icastz, Type::FloatTy,
  694. name("fz"));
  695. Value *fw = m_builder.CreateSIToFP(icastw, Type::FloatTy,
  696. name("fw"));
  697. return vectorFromVals(fx, fy, fz, fw);
  698. }
  699. llvm::Value * Instructions::x2d(llvm::Value *in1, llvm::Value *in2, llvm::Value *in3)
  700. {
  701. std::vector<llvm::Value*> vec1 = extractVector(in1);
  702. std::vector<llvm::Value*> vec2 = extractVector(in2);
  703. std::vector<llvm::Value*> vec3 = extractVector(in3);
  704. Value *x2x3 = m_builder.CreateMul( vec2[0], vec3[0], name("x2x3"));
  705. Value *y2y3 = m_builder.CreateMul( vec2[1], vec3[1], name("y2y3"));
  706. Value *x1px2x3 = m_builder.CreateAdd (vec1[0], x2x3, name("x1 + x2x3"));
  707. Value *x1px2x3py2y3 = m_builder.CreateAdd (x1px2x3, y2y3, name("x1 + x2x3 + y2y3"));
  708. Value *x2z3 = m_builder.CreateMul( vec2[0], vec3[2], name("x2z3"));
  709. Value *y2w3 = m_builder.CreateMul( vec2[1], vec3[3], name("y2w3"));
  710. Value *y1px2z3 = m_builder.CreateAdd (vec1[1], x2z3, name("y1 + x2z3"));
  711. Value *y1px2z3py2w3 = m_builder.CreateAdd (y1px2z3, y2w3, name("y1 + x2z3 + y2w3"));
  712. return vectorFromVals(x1px2x3py2y3, y1px2z3py2w3, x1px2x3py2y3, y1px2z3py2w3);
  713. }
  714. void Instructions::printVector(llvm::Value *val)
  715. {
  716. static const char *frmt = "Vector is [%f, %f, %f, %f]\x0A";
  717. if (!m_fmtPtr) {
  718. Constant *format = ConstantArray::get(frmt, true);
  719. ArrayType *arrayTy = ArrayType::get(IntegerType::get(8), strlen(frmt) + 1);
  720. GlobalVariable* globalFormat = new GlobalVariable(
  721. /*Type=*/arrayTy,
  722. /*isConstant=*/true,
  723. /*Linkage=*/GlobalValue::InternalLinkage,
  724. /*Initializer=*/0, // has initializer, specified below
  725. /*Name=*/name(".str"),
  726. m_mod);
  727. globalFormat->setInitializer(format);
  728. Constant* const_int0 = Constant::getNullValue(IntegerType::get(32));
  729. std::vector<Constant*> const_ptr_21_indices;
  730. const_ptr_21_indices.push_back(const_int0);
  731. const_ptr_21_indices.push_back(const_int0);
  732. m_fmtPtr = ConstantExpr::getGetElementPtr(globalFormat,
  733. &const_ptr_21_indices[0], const_ptr_21_indices.size());
  734. }
  735. Function *func_printf = m_mod->getFunction("printf");
  736. if (!func_printf)
  737. func_printf = declarePrintf();
  738. assert(func_printf);
  739. std::vector<llvm::Value*> vec = extractVector(val);
  740. Value *dx = m_builder.CreateFPExt(vec[0], Type::DoubleTy, name("dx"));
  741. Value *dy = m_builder.CreateFPExt(vec[1], Type::DoubleTy, name("dy"));
  742. Value *dz = m_builder.CreateFPExt(vec[2], Type::DoubleTy, name("dz"));
  743. Value *dw = m_builder.CreateFPExt(vec[3], Type::DoubleTy, name("dw"));
  744. std::vector<Value*> params;
  745. params.push_back(m_fmtPtr);
  746. params.push_back(dx);
  747. params.push_back(dy);
  748. params.push_back(dz);
  749. params.push_back(dw);
  750. CallInst *call = m_builder.CreateCall(func_printf, params.begin(), params.end(),
  751. name("printf"));
  752. call->setCallingConv(CallingConv::C);
  753. call->setTailCall(true);
  754. }
  755. const char * Instructions::name(const char *prefix)
  756. {
  757. ++m_idx;
  758. snprintf(m_name, 32, "%s%d", prefix, m_idx);
  759. return m_name;
  760. }
  761. llvm::Value * Instructions::callCeil(llvm::Value *val)
  762. {
  763. if (!m_llvmCeil) {
  764. // predeclare the intrinsic
  765. std::vector<const Type*> ceilArgs;
  766. ceilArgs.push_back(Type::FloatTy);
  767. PAListPtr ceilPal;
  768. FunctionType* ceilType = FunctionType::get(
  769. /*Result=*/Type::FloatTy,
  770. /*Params=*/ceilArgs,
  771. /*isVarArg=*/false);
  772. m_llvmCeil = Function::Create(
  773. /*Type=*/ceilType,
  774. /*Linkage=*/GlobalValue::ExternalLinkage,
  775. /*Name=*/"ceilf", m_mod);
  776. m_llvmCeil->setCallingConv(CallingConv::C);
  777. m_llvmCeil->setParamAttrs(ceilPal);
  778. }
  779. CallInst *call = m_builder.CreateCall(m_llvmCeil, val,
  780. name("ceilf"));
  781. call->setCallingConv(CallingConv::C);
  782. call->setTailCall(false);
  783. return call;
  784. }
  785. llvm::Value *Instructions::callFAbs(llvm::Value *val)
  786. {
  787. if (!m_llvmFAbs) {
  788. // predeclare the intrinsic
  789. std::vector<const Type*> fabsArgs;
  790. fabsArgs.push_back(Type::FloatTy);
  791. PAListPtr fabsPal;
  792. FunctionType* fabsType = FunctionType::get(
  793. /*Result=*/Type::FloatTy,
  794. /*Params=*/fabsArgs,
  795. /*isVarArg=*/false);
  796. m_llvmFAbs = Function::Create(
  797. /*Type=*/fabsType,
  798. /*Linkage=*/GlobalValue::ExternalLinkage,
  799. /*Name=*/"fabs", m_mod);
  800. m_llvmFAbs->setCallingConv(CallingConv::C);
  801. m_llvmFAbs->setParamAttrs(fabsPal);
  802. }
  803. CallInst *call = m_builder.CreateCall(m_llvmFAbs, val,
  804. name("fabs"));
  805. call->setCallingConv(CallingConv::C);
  806. call->setTailCall(false);
  807. return call;
  808. }
  809. llvm::Value * Instructions::callFExp(llvm::Value *val)
  810. {
  811. if (!m_llvmFexp) {
  812. // predeclare the intrinsic
  813. std::vector<const Type*> fexpArgs;
  814. fexpArgs.push_back(Type::FloatTy);
  815. PAListPtr fexpPal;
  816. FunctionType* fexpType = FunctionType::get(
  817. /*Result=*/Type::FloatTy,
  818. /*Params=*/fexpArgs,
  819. /*isVarArg=*/false);
  820. m_llvmFexp = Function::Create(
  821. /*Type=*/fexpType,
  822. /*Linkage=*/GlobalValue::ExternalLinkage,
  823. /*Name=*/"expf", m_mod);
  824. m_llvmFexp->setCallingConv(CallingConv::C);
  825. m_llvmFexp->setParamAttrs(fexpPal);
  826. }
  827. CallInst *call = m_builder.CreateCall(m_llvmFexp, val,
  828. name("expf"));
  829. call->setCallingConv(CallingConv::C);
  830. call->setTailCall(false);
  831. return call;
  832. }
  833. llvm::Value * Instructions::callFLog(llvm::Value *val)
  834. {
  835. if (!m_llvmFlog) {
  836. // predeclare the intrinsic
  837. std::vector<const Type*> flogArgs;
  838. flogArgs.push_back(Type::FloatTy);
  839. PAListPtr flogPal;
  840. FunctionType* flogType = FunctionType::get(
  841. /*Result=*/Type::FloatTy,
  842. /*Params=*/flogArgs,
  843. /*isVarArg=*/false);
  844. m_llvmFlog = Function::Create(
  845. /*Type=*/flogType,
  846. /*Linkage=*/GlobalValue::ExternalLinkage,
  847. /*Name=*/"logf", m_mod);
  848. m_llvmFlog->setCallingConv(CallingConv::C);
  849. m_llvmFlog->setParamAttrs(flogPal);
  850. }
  851. CallInst *call = m_builder.CreateCall(m_llvmFlog, val,
  852. name("logf"));
  853. call->setCallingConv(CallingConv::C);
  854. call->setTailCall(false);
  855. return call;
  856. }
  857. llvm::Value * Instructions::callFloor(llvm::Value *val)
  858. {
  859. if (!m_llvmFloor) {
  860. // predeclare the intrinsic
  861. std::vector<const Type*> floorArgs;
  862. floorArgs.push_back(Type::FloatTy);
  863. PAListPtr floorPal;
  864. FunctionType* floorType = FunctionType::get(
  865. /*Result=*/Type::FloatTy,
  866. /*Params=*/floorArgs,
  867. /*isVarArg=*/false);
  868. m_llvmFloor = Function::Create(
  869. /*Type=*/floorType,
  870. /*Linkage=*/GlobalValue::ExternalLinkage,
  871. /*Name=*/"floorf", m_mod);
  872. m_llvmFloor->setCallingConv(CallingConv::C);
  873. m_llvmFloor->setParamAttrs(floorPal);
  874. }
  875. CallInst *call = m_builder.CreateCall(m_llvmFloor, val,
  876. name("floorf"));
  877. call->setCallingConv(CallingConv::C);
  878. call->setTailCall(false);
  879. return call;
  880. }
  881. llvm::Value *Instructions::callFSqrt(llvm::Value *val)
  882. {
  883. if (!m_llvmFSqrt) {
  884. // predeclare the intrinsic
  885. std::vector<const Type*> fsqrtArgs;
  886. fsqrtArgs.push_back(Type::FloatTy);
  887. PAListPtr fsqrtPal;
  888. FunctionType* fsqrtType = FunctionType::get(
  889. /*Result=*/Type::FloatTy,
  890. /*Params=*/fsqrtArgs,
  891. /*isVarArg=*/false);
  892. m_llvmFSqrt = Function::Create(
  893. /*Type=*/fsqrtType,
  894. /*Linkage=*/GlobalValue::ExternalLinkage,
  895. /*Name=*/"llvm.sqrt.f32", m_mod);
  896. m_llvmFSqrt->setCallingConv(CallingConv::C);
  897. m_llvmFSqrt->setParamAttrs(fsqrtPal);
  898. }
  899. CallInst *call = m_builder.CreateCall(m_llvmFSqrt, val,
  900. name("sqrt"));
  901. call->setCallingConv(CallingConv::C);
  902. call->setTailCall(false);
  903. return call;
  904. }
  905. llvm::Value * Instructions::callPow(llvm::Value *val1, llvm::Value *val2)
  906. {
  907. if (!m_llvmPow) {
  908. // predeclare the intrinsic
  909. std::vector<const Type*> powArgs;
  910. powArgs.push_back(Type::FloatTy);
  911. powArgs.push_back(Type::FloatTy);
  912. PAListPtr powPal;
  913. FunctionType* powType = FunctionType::get(
  914. /*Result=*/Type::FloatTy,
  915. /*Params=*/powArgs,
  916. /*isVarArg=*/false);
  917. m_llvmPow = Function::Create(
  918. /*Type=*/powType,
  919. /*Linkage=*/GlobalValue::ExternalLinkage,
  920. /*Name=*/"llvm.pow.f32", m_mod);
  921. m_llvmPow->setCallingConv(CallingConv::C);
  922. m_llvmPow->setParamAttrs(powPal);
  923. }
  924. std::vector<Value*> params;
  925. params.push_back(val1);
  926. params.push_back(val2);
  927. CallInst *call = m_builder.CreateCall(m_llvmPow, params.begin(), params.end(),
  928. name("pow"));
  929. call->setCallingConv(CallingConv::C);
  930. call->setTailCall(false);
  931. return call;
  932. }
  933. llvm::Value * Instructions::vectorFromVals(llvm::Value *x, llvm::Value *y,
  934. llvm::Value *z, llvm::Value *w)
  935. {
  936. Constant *const_vec = Constant::getNullValue(m_floatVecType);
  937. Value *res = m_builder.CreateInsertElement(const_vec, x,
  938. m_storage->constantInt(0),
  939. name("vecx"));
  940. res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1),
  941. name("vecxy"));
  942. res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2),
  943. name("vecxyz"));
  944. if (w)
  945. res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3),
  946. name("vecxyzw"));
  947. return res;
  948. }
  949. llvm::Value * Instructions::constVector(float x, float y, float z, float w)
  950. {
  951. std::vector<Constant*> vec(4);
  952. vec[0] = ConstantFP::get(APFloat(x));
  953. vec[1] = ConstantFP::get(APFloat(y));
  954. vec[2] = ConstantFP::get(APFloat(z));
  955. vec[3] = ConstantFP::get(APFloat(w));
  956. return ConstantVector::get(m_floatVecType, vec);
  957. }
  958. llvm::Function * Instructions::declarePrintf()
  959. {
  960. std::vector<const Type*> args;
  961. PAListPtr params;
  962. FunctionType* funcTy = FunctionType::get(
  963. /*Result=*/IntegerType::get(32),
  964. /*Params=*/args,
  965. /*isVarArg=*/true);
  966. Function* func_printf = Function::Create(
  967. /*Type=*/funcTy,
  968. /*Linkage=*/GlobalValue::ExternalLinkage,
  969. /*Name=*/"printf", m_mod);
  970. func_printf->setCallingConv(CallingConv::C);
  971. func_printf->setParamAttrs(params);
  972. return func_printf;
  973. }
  974. llvm::Function * Instructions::declareFunc(int label)
  975. {
  976. PointerType *vecPtr = PointerType::getUnqual(m_floatVecType);
  977. std::vector<const Type*> args;
  978. args.push_back(vecPtr);
  979. args.push_back(vecPtr);
  980. args.push_back(vecPtr);
  981. args.push_back(vecPtr);
  982. PAListPtr params;
  983. FunctionType *funcType = FunctionType::get(
  984. /*Result=*/Type::VoidTy,
  985. /*Params=*/args,
  986. /*isVarArg=*/false);
  987. std::string name = createFuncName(label);
  988. Function *func = Function::Create(
  989. /*Type=*/funcType,
  990. /*Linkage=*/GlobalValue::ExternalLinkage,
  991. /*Name=*/name.c_str(), m_mod);
  992. func->setCallingConv(CallingConv::C);
  993. func->setParamAttrs(params);
  994. return func;
  995. }
  996. llvm::Function * Instructions::findFunction(int label)
  997. {
  998. llvm::Function *func = m_functions[label];
  999. if (!func) {
  1000. func = declareFunc(label);
  1001. m_functions[label] = func;
  1002. }
  1003. return func;
  1004. }
  1005. std::vector<llvm::Value*> Instructions::extractVector(llvm::Value *vec)
  1006. {
  1007. std::vector<llvm::Value*> elems(4);
  1008. elems[0] = m_builder.CreateExtractElement(vec, m_storage->constantInt(0),
  1009. name("x"));
  1010. elems[1] = m_builder.CreateExtractElement(vec, m_storage->constantInt(1),
  1011. name("y"));
  1012. elems[2] = m_builder.CreateExtractElement(vec, m_storage->constantInt(2),
  1013. name("z"));
  1014. elems[3] = m_builder.CreateExtractElement(vec, m_storage->constantInt(3),
  1015. name("w"));
  1016. return elems;
  1017. }
  1018. #endif //MESA_LLVM