12ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li/* 22ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * Copyright (C) 2005-2007 Brian Paul All Rights Reserved. 32ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * Copyright (C) 2008 VMware, Inc. All Rights Reserved. 42ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * Copyright © 2010 Intel Corporation 52ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * Copyright © 2010 Luca Barbieri 62ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * 72ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * Permission is hereby granted, free of charge, to any person obtaining a 82ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * copy of this software and associated documentation files (the "Software"), 92ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * to deal in the Software without restriction, including without limitation 102ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * the rights to use, copy, modify, merge, publish, distribute, sublicense, 112ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * and/or sell copies of the Software, and to permit persons to whom the 122ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * Software is furnished to do so, subject to the following conditions: 132ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * 142ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * The above copyright notice and this permission notice (including the next 152ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * paragraph) shall be included in all copies or substantial portions of the 162ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * Software. 172ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * 182ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 192ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 202ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 212ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 222ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 232ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 242ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * DEALINGS IN THE SOFTWARE. 252ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li */ 262ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 272ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li/** 282ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * \file ir_to_llvm.cpp 292ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * 302ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li * Translates the IR to LLVM 312ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li */ 322ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 332ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li/* this tends to get set as part of LLVM_CFLAGS, but we definitely want asserts */ 342ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#ifdef NDEBUG 352ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#undef NDEBUG 362ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#endif 372ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 386730e48003ab09afe8c3c0c555ba5dee013ffc74Shih-wei Liao#include "llvm/ADT/ArrayRef.h" 392ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#include "llvm/DerivedTypes.h" 402ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#include "llvm/LLVMContext.h" 412ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#include "llvm/Module.h" 422ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#include "llvm/Analysis/Verifier.h" 432ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#include "llvm/Support/IRBuilder.h" 44d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li//#include "llvm/Intrinsics.h" 452ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 462ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#include <vector> 472ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#include <stdio.h> 48d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li#include <map> 49d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li/* 502ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#ifdef _MSC_VER 512ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#include <unordered_map> 522ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#else 532ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#include <tr1/unordered_map> 542ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#endif 552ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li// use C++0x/Microsoft convention 562ccfc245453738134c327ebd5f5dd189a7a6184bDavid Linamespace std 572ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li{ 58d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Liusing namespace tr1; 592ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li} 60d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li//*/ 612ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 622ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#include "ir.h" 632ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#include "ir_visitor.h" 642ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li#include "glsl_types.h" 65e82376d380005c21cb70637d42104fcd4d652843David Li#include "src/mesa/main/mtypes.h" 662ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 676730e48003ab09afe8c3c0c555ba5dee013ffc74Shih-wei Liao// Helper function to convert array to llvm::ArrayRef 686730e48003ab09afe8c3c0c555ba5dee013ffc74Shih-wei Liaotemplate <typename T, size_t N> 696730e48003ab09afe8c3c0c555ba5dee013ffc74Shih-wei Liaostatic inline llvm::ArrayRef<T> pack(T const (&array)[N]) { 706730e48003ab09afe8c3c0c555ba5dee013ffc74Shih-wei Liao return llvm::ArrayRef<T>(array); 716730e48003ab09afe8c3c0c555ba5dee013ffc74Shih-wei Liao} 726730e48003ab09afe8c3c0c555ba5dee013ffc74Shih-wei Liao 736730e48003ab09afe8c3c0c555ba5dee013ffc74Shih-wei Liao// Helper function to convert pointer + size to llvm::ArrayRef 746730e48003ab09afe8c3c0c555ba5dee013ffc74Shih-wei Liaotemplate <typename T> 756730e48003ab09afe8c3c0c555ba5dee013ffc74Shih-wei Liaostatic inline llvm::ArrayRef<T> pack(T const *ptr, size_t n) { 766730e48003ab09afe8c3c0c555ba5dee013ffc74Shih-wei Liao return llvm::ArrayRef<T>(ptr, n); 776730e48003ab09afe8c3c0c555ba5dee013ffc74Shih-wei Liao} 786730e48003ab09afe8c3c0c555ba5dee013ffc74Shih-wei Liao 792ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Listruct GGLState; 8013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 8113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Lillvm::Value * tex2D(llvm::IRBuilder<> & builder, llvm::Value * in1, const unsigned sampler, 822ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li const GGLState * gglCtx); 8313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Lillvm::Value * texCube(llvm::IRBuilder<> & builder, llvm::Value * in1, const unsigned sampler, 842ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li const GGLState * gglCtx); 8513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 862ccfc245453738134c327ebd5f5dd189a7a6184bDavid Liclass ir_to_llvm_visitor : public ir_visitor { 872ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li ir_to_llvm_visitor(); 8813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Lipublic: 8913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li 902ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 912ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::LLVMContext& ctx; 922ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Module* mod; 932ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Function* fun; 942ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li // could easily support more loops, but GLSL doesn't support multiloop break/continue 952ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li std::pair<llvm::BasicBlock*, llvm::BasicBlock*> loop; 962ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::BasicBlock* bb; 972ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* result; 982ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::IRBuilder<> bld; 996426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao 1002ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li const GGLState * gglCtx; 101e82376d380005c21cb70637d42104fcd4d652843David Li const char * shaderSuffix; 102470970d77c095678830fc512dfe0e97c6bcab15bDavid Li llvm::Value * inputsPtr, * outputsPtr, * constantsPtr; // internal globals to store inputs/outputs/constants pointers 103470970d77c095678830fc512dfe0e97c6bcab15bDavid Li llvm::Value * inputs, * outputs, * constants; 1046426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao 1052ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li ir_to_llvm_visitor(llvm::Module* p_mod, const GGLState * GGLCtx, const char * suffix) 1066426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao : ctx(p_mod->getContext()), mod(p_mod), fun(0), loop(std::make_pair((llvm::BasicBlock*)0, 107470970d77c095678830fc512dfe0e97c6bcab15bDavid Li (llvm::BasicBlock*)0)), bb(0), bld(ctx), gglCtx(GGLCtx), shaderSuffix(suffix), 108470970d77c095678830fc512dfe0e97c6bcab15bDavid Li inputsPtr(NULL), outputsPtr(NULL), constantsPtr(NULL), 109470970d77c095678830fc512dfe0e97c6bcab15bDavid Li inputs(NULL), outputs(NULL), constants(NULL) 1102ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 111ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien llvm::PointerType * const floatVecPtrType = llvm::PointerType::get(llvm::VectorType::get(bld.getFloatTy(),4), 0); 112470970d77c095678830fc512dfe0e97c6bcab15bDavid Li llvm::Constant * const nullFloatVecPtr = llvm::Constant::getNullValue(floatVecPtrType); 113470970d77c095678830fc512dfe0e97c6bcab15bDavid Li // make input, output and consts global pointers so they can be used in 114470970d77c095678830fc512dfe0e97c6bcab15bDavid Li // different LLVM functions since the shader shares these "registers" across "functions" 1156426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao 1166426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao inputsPtr = new llvm::GlobalVariable(*mod, floatVecPtrType, false, 1176426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao llvm::GlobalValue::InternalLinkage, nullFloatVecPtr, "gl_inputPtr"); 118470970d77c095678830fc512dfe0e97c6bcab15bDavid Li 119470970d77c095678830fc512dfe0e97c6bcab15bDavid Li outputsPtr = new llvm::GlobalVariable(*mod, floatVecPtrType, false, 1206426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao llvm::GlobalValue::InternalLinkage, nullFloatVecPtr, "gl_outputsPtr"); 1216426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao 1226426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao constantsPtr = new llvm::GlobalVariable(*mod, floatVecPtrType, false, 1236426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao llvm::GlobalValue::InternalLinkage, nullFloatVecPtr, "gl_constantsPtr"); 1242ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 1252ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 126ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien llvm::Type* llvm_base_type(unsigned base_type) 1272ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 1282ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch(base_type) 1292ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 1302ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_VOID: 1312ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return llvm::Type::getVoidTy(ctx); 1322ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 1332ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 1342ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return llvm::Type::getInt32Ty(ctx); 1352ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 1362ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return llvm::Type::getFloatTy(ctx); 1372ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 1382ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return llvm::Type::getInt1Ty(ctx); 1392ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_SAMPLER: 1402ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return llvm::PointerType::getUnqual(llvm::Type::getVoidTy(ctx)); 1412ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 1422ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 1432ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return 0; 1442ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 1452ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 1462ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 1470783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao llvm::Type* llvm_vec_type(const glsl_type* type) 1482ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 1490783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao if (type->is_array()) 1502ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return llvm::ArrayType::get(llvm_type(type->fields.array), type->array_size()); 1512ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 1520783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao if (type->is_record()) 1532ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 15482a20bd6b8b3e26b04b9fcfe9933e9807177c801Shih-wei Liao std::vector<llvm::Type*> fields; 1552ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li for (unsigned i = 0; i < type->length; i++) 1562ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li fields.push_back(llvm_type(type->fields.structure[i].type)); 15782a20bd6b8b3e26b04b9fcfe9933e9807177c801Shih-wei Liao return llvm::StructType::get(ctx, llvm::ArrayRef<llvm::Type*>( 15882a20bd6b8b3e26b04b9fcfe9933e9807177c801Shih-wei Liao fields)); 1592ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 1602ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 161ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien llvm::Type* base_type = llvm_base_type(type->base_type); 1620783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao if (type->vector_elements <= 1) { 1632ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return base_type; 1640783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao } else { 1652ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return llvm::VectorType::get(base_type, type->vector_elements); 1660783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao } 1672ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 1682ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 1690783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao llvm::Type* llvm_type(const glsl_type* type) 1702ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 1710783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao llvm::Type* vec_type = llvm_vec_type(type); 1720783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao if (type->matrix_columns <= 1) { 1732ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return vec_type; 1740783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao } else { 1752ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return llvm::ArrayType::get(vec_type, type->matrix_columns); 1760783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao } 1772ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 1782ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 179d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li typedef std::map<ir_variable*, llvm::Value*> llvm_variables_t; 180d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li //typedef std::unordered_map<ir_variable*, llvm::Value*> llvm_variables_t; 1812ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm_variables_t llvm_variables; 1822ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 1832ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* llvm_variable(class ir_variable* var) 1842ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 1852ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm_variables_t::iterator vari = llvm_variables.find(var); 1860783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao if (vari != llvm_variables.end()) { 1872ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return vari->second; 1880783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao } else { 189ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien llvm::Type* type = llvm_type(var->type); 1902ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 191470970d77c095678830fc512dfe0e97c6bcab15bDavid Li llvm::Value* v = NULL; 1920783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao if(fun) { 193470970d77c095678830fc512dfe0e97c6bcab15bDavid Li if (ir_var_in == var->mode) 194470970d77c095678830fc512dfe0e97c6bcab15bDavid Li { 195470970d77c095678830fc512dfe0e97c6bcab15bDavid Li assert(var->location >= 0); 196470970d77c095678830fc512dfe0e97c6bcab15bDavid Li v = bld.CreateConstGEP1_32(inputs, var->location); 197470970d77c095678830fc512dfe0e97c6bcab15bDavid Li v = bld.CreateBitCast(v, llvm::PointerType::get(llvm_type(var->type), 0), var->name); 198470970d77c095678830fc512dfe0e97c6bcab15bDavid Li } 199470970d77c095678830fc512dfe0e97c6bcab15bDavid Li else if (ir_var_out == var->mode) 200470970d77c095678830fc512dfe0e97c6bcab15bDavid Li { 201470970d77c095678830fc512dfe0e97c6bcab15bDavid Li assert(var->location >= 0); 202470970d77c095678830fc512dfe0e97c6bcab15bDavid Li v = bld.CreateConstGEP1_32(outputs, var->location); 203470970d77c095678830fc512dfe0e97c6bcab15bDavid Li v = bld.CreateBitCast(v, llvm::PointerType::get(llvm_type(var->type), 0), var->name); 204470970d77c095678830fc512dfe0e97c6bcab15bDavid Li } 205470970d77c095678830fc512dfe0e97c6bcab15bDavid Li else if (ir_var_uniform == var->mode) 206470970d77c095678830fc512dfe0e97c6bcab15bDavid Li { 207470970d77c095678830fc512dfe0e97c6bcab15bDavid Li assert(var->location >= 0); 208470970d77c095678830fc512dfe0e97c6bcab15bDavid Li v = bld.CreateConstGEP1_32(constants, var->location); 209470970d77c095678830fc512dfe0e97c6bcab15bDavid Li v = bld.CreateBitCast(v, llvm::PointerType::get(llvm_type(var->type), 0), var->name); 210470970d77c095678830fc512dfe0e97c6bcab15bDavid Li } 2112ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else 212470970d77c095678830fc512dfe0e97c6bcab15bDavid Li { 213470970d77c095678830fc512dfe0e97c6bcab15bDavid Li if(bb == &fun->getEntryBlock()) 214470970d77c095678830fc512dfe0e97c6bcab15bDavid Li v = bld.CreateAlloca(type, 0, var->name); 215470970d77c095678830fc512dfe0e97c6bcab15bDavid Li else 216470970d77c095678830fc512dfe0e97c6bcab15bDavid Li v = new llvm::AllocaInst(type, 0, var->name, fun->getEntryBlock().getTerminator()); 217470970d77c095678830fc512dfe0e97c6bcab15bDavid Li } 2180783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao } else { 2190783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao // TODO: can anything global be non-constant in GLSL?; fix linkage 220470970d77c095678830fc512dfe0e97c6bcab15bDavid Li //printf("var '%s' mode=%d location=%d \n", var->name, var->mode, var->location); 221470970d77c095678830fc512dfe0e97c6bcab15bDavid Li switch(var->mode) 222fee3eee644164b2dc85a5dcf654ce75367f32a4eDavid Li { 223470970d77c095678830fc512dfe0e97c6bcab15bDavid Li case ir_var_auto: // fall through 224470970d77c095678830fc512dfe0e97c6bcab15bDavid Li case ir_var_temporary: 225470970d77c095678830fc512dfe0e97c6bcab15bDavid Li { 226470970d77c095678830fc512dfe0e97c6bcab15bDavid Li llvm::Constant * init = llvm::UndefValue::get(llvm_type(var->type)); 227470970d77c095678830fc512dfe0e97c6bcab15bDavid Li if(var->constant_value) 228470970d77c095678830fc512dfe0e97c6bcab15bDavid Li init = llvm_constant(var->constant_value); 229470970d77c095678830fc512dfe0e97c6bcab15bDavid Li v = new llvm::GlobalVariable(*mod, type, var->read_only, llvm::GlobalValue::InternalLinkage, init, var->name); 230470970d77c095678830fc512dfe0e97c6bcab15bDavid Li break; 231470970d77c095678830fc512dfe0e97c6bcab15bDavid Li } 232470970d77c095678830fc512dfe0e97c6bcab15bDavid Li case ir_var_in: // fall through 233470970d77c095678830fc512dfe0e97c6bcab15bDavid Li case ir_var_out: // fall through 234470970d77c095678830fc512dfe0e97c6bcab15bDavid Li case ir_var_uniform: // fall through 235470970d77c095678830fc512dfe0e97c6bcab15bDavid Li assert(var->location >= 0); 236470970d77c095678830fc512dfe0e97c6bcab15bDavid Li return NULL; // variable outside of function means declaration 237470970d77c095678830fc512dfe0e97c6bcab15bDavid Li default: 238470970d77c095678830fc512dfe0e97c6bcab15bDavid Li assert(0); 239fee3eee644164b2dc85a5dcf654ce75367f32a4eDavid Li } 240470970d77c095678830fc512dfe0e97c6bcab15bDavid Li 241470970d77c095678830fc512dfe0e97c6bcab15bDavid Li// llvm::Function::LinkageTypes linkage; 242470970d77c095678830fc512dfe0e97c6bcab15bDavid Li// if(var->mode == ir_var_auto || var->mode == ir_var_temporary) 243470970d77c095678830fc512dfe0e97c6bcab15bDavid Li// linkage = llvm::GlobalValue::InternalLinkage; 244470970d77c095678830fc512dfe0e97c6bcab15bDavid Li// else 245470970d77c095678830fc512dfe0e97c6bcab15bDavid Li// linkage = llvm::GlobalValue::ExternalLinkage; 246470970d77c095678830fc512dfe0e97c6bcab15bDavid Li// llvm::Constant* init = 0; 247470970d77c095678830fc512dfe0e97c6bcab15bDavid Li// if(var->constant_value) 248470970d77c095678830fc512dfe0e97c6bcab15bDavid Li// { 249470970d77c095678830fc512dfe0e97c6bcab15bDavid Li// init = llvm_constant(var->constant_value); 250470970d77c095678830fc512dfe0e97c6bcab15bDavid Li// // this constants need to be external (ie. written to output) 251470970d77c095678830fc512dfe0e97c6bcab15bDavid Li// if (llvm::GlobalValue::ExternalLinkage == linkage) 252470970d77c095678830fc512dfe0e97c6bcab15bDavid Li// linkage = llvm::GlobalValue::AvailableExternallyLinkage; 253470970d77c095678830fc512dfe0e97c6bcab15bDavid Li// } 254470970d77c095678830fc512dfe0e97c6bcab15bDavid Li// else if(linkage == llvm::GlobalValue::InternalLinkage) 255470970d77c095678830fc512dfe0e97c6bcab15bDavid Li// init = llvm::UndefValue::get(llvm_type(var->type)); 256470970d77c095678830fc512dfe0e97c6bcab15bDavid Li// v = new llvm::GlobalVariable(*mod, type, var->read_only, linkage, init, var->name); 2572ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 258470970d77c095678830fc512dfe0e97c6bcab15bDavid Li assert(v); 2592ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm_variables[var] = v; 2602ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return v; 2612ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 2622ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 2632ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 264e82376d380005c21cb70637d42104fcd4d652843David Li //typedef std::map<ir_function_signature*, llvm::Function*> llvm_functions_t; 265d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li //typedef std::unordered_map<ir_function_signature*, llvm::Function*> llvm_functions_t; 266e82376d380005c21cb70637d42104fcd4d652843David Li //llvm_functions_t llvm_functions; 2672ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 2682ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Function* llvm_function(class ir_function_signature* sig) 2692ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 270e82376d380005c21cb70637d42104fcd4d652843David Li const char* name = sig->function_name(); 271e82376d380005c21cb70637d42104fcd4d652843David Li char * functionName = (char *)malloc(strlen(name) + strlen(shaderSuffix) + 1); 272e82376d380005c21cb70637d42104fcd4d652843David Li strcpy(functionName, name); 273e82376d380005c21cb70637d42104fcd4d652843David Li strcat(functionName, shaderSuffix); 274e82376d380005c21cb70637d42104fcd4d652843David Li llvm::Function * function = mod->getFunction(functionName); 275e82376d380005c21cb70637d42104fcd4d652843David Li if (function) 276e82376d380005c21cb70637d42104fcd4d652843David Li { 277e82376d380005c21cb70637d42104fcd4d652843David Li free(functionName); 278e82376d380005c21cb70637d42104fcd4d652843David Li return function; 279e82376d380005c21cb70637d42104fcd4d652843David Li } 2802ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else 2812ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 2822ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Function::LinkageTypes linkage; 28382a20bd6b8b3e26b04b9fcfe9933e9807177c801Shih-wei Liao std::vector<llvm::Type*> params; 2842ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li foreach_iter(exec_list_iterator, iter, sig->parameters) { 2852ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li ir_variable* arg = (ir_variable*)iter.get(); 2862ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li params.push_back(llvm_type(arg->type)); 2872ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 2886426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao 289470970d77c095678830fc512dfe0e97c6bcab15bDavid Li if(!strcmp(name, "main") || !sig->is_defined) 290470970d77c095678830fc512dfe0e97c6bcab15bDavid Li { 291470970d77c095678830fc512dfe0e97c6bcab15bDavid Li linkage = llvm::Function::ExternalLinkage; 292470970d77c095678830fc512dfe0e97c6bcab15bDavid Li llvm::PointerType * vecPtrTy = llvm::PointerType::get(llvm::VectorType::get(bld.getFloatTy(), 4), 0); 293470970d77c095678830fc512dfe0e97c6bcab15bDavid Li assert(0 == params.size()); 294470970d77c095678830fc512dfe0e97c6bcab15bDavid Li params.push_back(vecPtrTy); // inputs 295470970d77c095678830fc512dfe0e97c6bcab15bDavid Li params.push_back(vecPtrTy); // outputs 296470970d77c095678830fc512dfe0e97c6bcab15bDavid Li params.push_back(vecPtrTy); // constants 297470970d77c095678830fc512dfe0e97c6bcab15bDavid Li } 29882a20bd6b8b3e26b04b9fcfe9933e9807177c801Shih-wei Liao else { 299470970d77c095678830fc512dfe0e97c6bcab15bDavid Li linkage = llvm::Function::InternalLinkage; 30082a20bd6b8b3e26b04b9fcfe9933e9807177c801Shih-wei Liao } 30182a20bd6b8b3e26b04b9fcfe9933e9807177c801Shih-wei Liao llvm::FunctionType* ft = llvm::FunctionType::get(llvm_type(sig->return_type), 30282a20bd6b8b3e26b04b9fcfe9933e9807177c801Shih-wei Liao llvm::ArrayRef<llvm::Type*>(params), 30382a20bd6b8b3e26b04b9fcfe9933e9807177c801Shih-wei Liao false); 304e82376d380005c21cb70637d42104fcd4d652843David Li function = llvm::Function::Create(ft, linkage, functionName, mod); 305e82376d380005c21cb70637d42104fcd4d652843David Li free(functionName); 306e82376d380005c21cb70637d42104fcd4d652843David Li return function; 3072ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 3082ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 3092ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 3102ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* llvm_value(class ir_instruction* ir) 3112ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 3122ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li result = 0; 3132ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li ir->accept(this); 3142ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return result; 3152ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 3162ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 3172ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Constant* llvm_constant(class ir_instruction* ir) 3182ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 319d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return (llvm::Constant *)llvm_value(ir); 320d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li //return &dynamic_cast<llvm::Constant&>(*llvm_value(ir)); 3212ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 3222ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 3232ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Constant* llvm_int(unsigned v) 3242ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 3252ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return llvm::ConstantInt::get(llvm::Type::getInt32Ty(ctx), v); 3262ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 3272ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 3282ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* llvm_pointer(class ir_rvalue* ir) 3292ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 3302ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(ir_dereference_variable* deref = ir->as_dereference_variable()) 3312ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return llvm_variable(deref->variable_referenced()); 3322ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else if(ir_dereference_array* deref = ir->as_dereference_array()) 3332ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 3342ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* gep[2] = {llvm_int(0), llvm_value(deref->array_index)}; 3358a0502c8141f8bed72f9da5c7ca663604a268313Logan Chien return bld.CreateInBoundsGEP(llvm_pointer(deref->array), gep); 3362ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 3372ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else if(ir->as_dereference()) 3382ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 3392ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li ir_dereference_record* deref = (ir_dereference_record*)ir; 3402ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li int idx = deref->record->type->field_index(deref->field); 3412ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(idx >= 0); 3422ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateConstInBoundsGEP2_32(llvm_pointer(deref->record), 0, idx); 3432ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 3442ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else 3452ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 3462ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 3472ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return 0; 3482ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 3492ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 3502ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 351d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// llvm::Value* llvm_intrinsic(llvm::Intrinsic::ID id, llvm::Value* a) 352d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// { 353ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien// llvm::Type* types[1] = {a->getType()}; 354d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// return bld.CreateCall(llvm::Intrinsic::getDeclaration(mod, id, types, 1), a); 355d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// } 356d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// 357d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// llvm::Value* llvm_intrinsic(llvm::Intrinsic::ID id, llvm::Value* a, llvm::Value* b) 358d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// { 359ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien// llvm::Type* types[2] = {a->getType(), b->getType()}; 360d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// /* only one type suffix is usually needed, so pass 1 here */ 361d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// return bld.CreateCall2(llvm::Intrinsic::getDeclaration(mod, id, types, 1), a, b); 362d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// } 363d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li 364d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm::Value* llvm_intrinsic_unop(ir_expression_operation op, llvm::Value * op0) 3652ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 3660783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao llvm::Type * floatType = llvm::Type::getFloatTy(ctx); 367d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li const char * name = NULL; 368d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li switch (op) { 369d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case ir_unop_sin: 370d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li name = "sinf"; 371d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li break; 372d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case ir_unop_cos: 373d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li name = "cosf"; 374d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li break; 375d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li default: 376d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li assert(0); 377d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li } 378d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li 379d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm::Function * function = mod->getFunction(name); 380d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li if (!function) { 381d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li // predeclare the intrinsic 38282a20bd6b8b3e26b04b9fcfe9933e9807177c801Shih-wei Liao std::vector<llvm::Type*> args; 383d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li args.push_back(floatType); 38482a20bd6b8b3e26b04b9fcfe9933e9807177c801Shih-wei Liao llvm::FunctionType* type = llvm::FunctionType::get(floatType, 38582a20bd6b8b3e26b04b9fcfe9933e9807177c801Shih-wei Liao llvm::ArrayRef<llvm::Type*>(args), 38682a20bd6b8b3e26b04b9fcfe9933e9807177c801Shih-wei Liao false); 387d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li function = llvm::Function::Create(type, llvm::Function::ExternalLinkage, name, mod); 388d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li function->setCallingConv(llvm::CallingConv::C); 389d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li } 390d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li 391d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return bld.CreateCall(function, op0); 3922ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 3932ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 394d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm::Value* llvm_intrinsic_binop(ir_expression_operation op, llvm::Value * op0, llvm::Value * op1) 3952ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 3960783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao llvm::Type * floatType = llvm::Type::getFloatTy(ctx); 397d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li const char * name = NULL; 398d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li switch (op) { 399d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case ir_binop_pow: 400d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li name = "powf"; 401d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li break; 402d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li default: 403d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li assert(0); 404d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li } 405d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li 406d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm::Function * function = mod->getFunction(name); 407d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li if (!function) { 408d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li // predeclare the intrinsic 40982a20bd6b8b3e26b04b9fcfe9933e9807177c801Shih-wei Liao std::vector<llvm::Type*> args; 410d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li args.push_back(floatType); 411d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li args.push_back(floatType); 41282a20bd6b8b3e26b04b9fcfe9933e9807177c801Shih-wei Liao llvm::FunctionType* type = llvm::FunctionType::get(floatType, 41382a20bd6b8b3e26b04b9fcfe9933e9807177c801Shih-wei Liao llvm::ArrayRef<llvm::Type*>(args), 41482a20bd6b8b3e26b04b9fcfe9933e9807177c801Shih-wei Liao false); 415d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li function = llvm::Function::Create(type, llvm::Function::ExternalLinkage, name, mod); 416d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li function->setCallingConv(llvm::CallingConv::C); 417d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li } 418d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li 419d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return bld.CreateCall2(function, op0, op1); 4202ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 4212ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 4220783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao llvm::Constant* llvm_imm(llvm::Type* type, double v) 4232ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 4242ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(type->isVectorTy()) 4252ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 4262ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li std::vector<llvm::Constant*> values; 4272ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li values.push_back(llvm_imm(((llvm::VectorType*)type)->getElementType(), v)); 4282ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li for(unsigned i = 1; i < ((llvm::VectorType*)type)->getNumElements(); ++i) 4292ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li values.push_back(values[0]); 4302ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return llvm::ConstantVector::get(values); 4312ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 4322ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else if(type->isIntegerTy()) 4332ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return llvm::ConstantInt::get(type, v); 4342ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else if(type->isFloatingPointTy()) 4352ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return llvm::ConstantFP::get(type, v); 4362ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else 4372ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 4382ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 4392ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return 0; 4402ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 4412ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 4422ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 4432ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li static llvm::Value* create_shuffle3(llvm::IRBuilder<>& bld, llvm::Value* v, unsigned a, unsigned b, unsigned c, const llvm::Twine& name = "") 4442ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 445ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien llvm::Type* int_ty = llvm::Type::getInt32Ty(v->getContext()); 4466730e48003ab09afe8c3c0c555ba5dee013ffc74Shih-wei Liao llvm::Constant* vals[3] = {llvm::ConstantInt::get(int_ty, a), llvm::ConstantInt::get(int_ty, b), llvm::ConstantInt::get(int_ty, c)}; 4476730e48003ab09afe8c3c0c555ba5dee013ffc74Shih-wei Liao return bld.CreateShuffleVector(v, llvm::UndefValue::get(v->getType()), llvm::ConstantVector::get(pack(vals)), name); 4482ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 4492ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 450d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm::Value* create_select(unsigned width, llvm::Value * cond, llvm::Value * tru, llvm::Value * fal, const char * name = "") 451d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li { 452d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li if (1 == width) 453d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return bld.CreateSelect(cond, tru, fal, name); 454d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li 455ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien llvm::Type * vectorType = tru->getType(); 456d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm::Value * vector = llvm::Constant::getNullValue(vectorType); 457d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li for (unsigned int i = 0; i < width; i++) { 458d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm::Value * c = bld.CreateExtractElement(cond, llvm_int(i)); 459d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm::Value * t = bld.CreateExtractElement(tru, llvm_int(i)); 460d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm::Value * f = bld.CreateExtractElement(fal, llvm_int(i)); 461d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm::Value * v = bld.CreateSelect(c, t, f, name); 462d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li vector = bld.CreateInsertElement(vector, v, llvm_int(i), "vslct"); 463d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li } 464d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return vector; 465d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li } 466d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li 467d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm::Value* create_dot_product(llvm::Value* ops0, llvm::Value* ops1, glsl_base_type type, unsigned width) 468d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li { 469d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm::Value* prod; 470d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li switch (type) { 471d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case GLSL_TYPE_UINT: 472d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case GLSL_TYPE_INT: 473d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li prod = bld.CreateMul(ops0, ops1, "dot.mul"); 474d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li break; 475d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case GLSL_TYPE_FLOAT: 476d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li prod = bld.CreateFMul(ops0, ops1, "dot.mul"); 477d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li break; 478d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li default: 479d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li assert(0); 480d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li } 481d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li 482d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li if (width<= 1) 483d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return prod; 484d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li 485d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm::Value* sum = 0; 486d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li for (unsigned i = 0; i < width; ++i) { 487d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm::Value* elem = bld.CreateExtractElement(prod, llvm_int(i), "dot.elem"); 488d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li if (sum) { 489d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li if (type == GLSL_TYPE_FLOAT) 490d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li sum = bld.CreateFAdd(sum, elem, "dot.add"); 491d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li else 492d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li sum = bld.CreateAdd(sum, elem, "dot.add"); 493d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li } 494d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li else 495d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li sum = elem; 496d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li } 497d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return sum; 498d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li } 499d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li 5002ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* llvm_expression(ir_expression* ir) 5012ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 5022ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* ops[2]; 5032ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li for(unsigned i = 0; i < ir->get_num_operands(); ++i) 5042ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li ops[i] = llvm_value(ir->operands[i]); 5052ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 5062ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(ir->get_num_operands() == 2) 5072ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 5082ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li int vecidx = -1; 5092ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li int scaidx = -1; 5102ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(ir->operands[0]->type->vector_elements <= 1 && ir->operands[1]->type->vector_elements > 1) 5112ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 5122ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li scaidx = 0; 5132ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li vecidx = 1; 5142ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 5152ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else if(ir->operands[0]->type->vector_elements > 1 && ir->operands[1]->type->vector_elements <= 1) 5162ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 5172ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li scaidx = 1; 5182ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li vecidx = 0; 5192ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 5202ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else 5212ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(ir->operands[0]->type->vector_elements == ir->operands[1]->type->vector_elements); 5222ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 5232ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(scaidx >= 0) 5242ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 5252ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* vec; 5262ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li vec = llvm::UndefValue::get(ops[vecidx]->getType()); 5272ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li for(unsigned i = 0; i < ir->operands[vecidx]->type->vector_elements; ++i) 5282ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li vec = bld.CreateInsertElement(vec, ops[scaidx], llvm_int(i), "sca2vec"); 5292ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li ops[scaidx] = vec; 5302ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 5312ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 5322ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 5332ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch (ir->operation) { 5342ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_logic_not: 5352ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateNot(ops[0]); 5362ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_neg: 537d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li switch (ir->operands[0]->type->base_type) { 538d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case GLSL_TYPE_UINT: 539d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case GLSL_TYPE_BOOL: 540d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case GLSL_TYPE_INT: 541d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return bld.CreateNeg(ops[0]); 542d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case GLSL_TYPE_FLOAT: 543d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return bld.CreateFNeg(ops[0]); 544d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li default: 545d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li assert(0); 546d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li } 5472ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_abs: 548d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li switch (ir->operands[0]->type->base_type) { 5492ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 5502ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 5512ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return ops[0]; 5522ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 553d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return create_select(ir->operands[0]->type->vector_elements, 554d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li bld.CreateICmpSGE(ops[0], llvm_imm(ops[0]->getType(), 0), "sabs.ge"), 555d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li ops[0], bld.CreateNeg(ops[0], "sabs.neg"), "sabs.select"); 5562ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 557d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return create_select(ir->operands[0]->type->vector_elements, 558d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li bld.CreateFCmpUGE(ops[0], llvm_imm(ops[0]->getType(), 0), "fabs.ge"), 559d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li ops[0], bld.CreateFNeg(ops[0], "fabs.neg"), "fabs.select"); 5602ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 5612ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 5622ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 5632ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_sign: 564d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li switch (ir->operands[0]->type->base_type) { 5652ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 5662ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return ops[0]; 5672ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 5682ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateZExt(bld.CreateICmpNE(ops[0], llvm_imm(ops[0]->getType(), 0), "usign.ne"), ops[0]->getType(), "usign.zext"); 5692ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 5702ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateSelect(bld.CreateICmpNE(ops[0], llvm_imm(ops[0]->getType(), 0), "ssign.ne"), 571d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li bld.CreateSelect(bld.CreateICmpSGE(ops[0], llvm_imm(ops[0]->getType(), 0), "ssign.ge"), llvm_imm(ops[0]->getType(), 1), llvm_imm(ops[0]->getType(), -1), "sabs.selects"), 572d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm_imm(ops[0]->getType(), 0), "sabs.select0"); 5732ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 5742ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateSelect(bld.CreateFCmpONE(ops[0], llvm_imm(ops[0]->getType(), 0), "fsign.ne"), 575d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li bld.CreateSelect(bld.CreateFCmpUGE(ops[0], llvm_imm(ops[0]->getType(), 0), "fsign.ge"), llvm_imm(ops[0]->getType(), 1), llvm_imm(ops[0]->getType(), -1), "fabs.selects"), 576d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm_imm(ops[0]->getType(), 0), "fabs.select0"); 5772ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 5782ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 5792ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 5802ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_rcp: 5812ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); 5822ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateFDiv(llvm_imm(ops[0]->getType(), 1), ops[0]); 583d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case ir_unop_exp: // fall through 584d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case ir_unop_exp2: // fall through 585d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case ir_unop_log: // fall through 586d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case ir_unop_log2: // fall through 587d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case ir_unop_sin: // fall through 5882ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_cos: 5892ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); 590d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return llvm_intrinsic_unop(ir->operation, ops[0]); 591d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li // TODO: implement these somehow 5922ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_dFdx: 5932ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 5942ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li //return llvm_intrinsic(llvm::Intrinsic::ddx, ops[0]); 5952ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_dFdy: 5962ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 5972ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li //return llvm_intrinsic(llvm::Intrinsic::ddy, ops[0]); 5982ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_add: 5992ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch(ir->operands[0]->type->base_type) 6002ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 6012ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 6022ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 6032ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 6042ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateAdd(ops[0], ops[1]); 6052ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 6062ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateFAdd(ops[0], ops[1]); 6072ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 6082ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 6092ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 6102ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_sub: 6112ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch(ir->operands[0]->type->base_type) 6122ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 6132ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 6142ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 6152ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 6162ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateSub(ops[0], ops[1]); 6172ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 6182ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateFSub(ops[0], ops[1]); 6192ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 6202ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 6212ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 622d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case ir_binop_mul: 623d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li if (ir->operands[0]->type->is_matrix() && ir->operands[1]->type->is_vector()) 624d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li assert(0); 625d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li else if (ir->operands[0]->type->is_vector() && ir->operands[1]->type->is_matrix()) { 626d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li assert(0); // matrix multiplication should have been lowered to vector ops 627d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm::VectorType * vectorType = llvm::VectorType::get(llvm_base_type(ir->operands[1]->type->base_type), ir->operands[1]->type->matrix_columns); 628d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm::Value * vector = llvm::Constant::getNullValue(vectorType); 629d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li for (unsigned int i = 0; i < ir->operands[1]->type->matrix_columns; i++) { 630d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li llvm::Value * value = bld.CreateExtractValue(ops[1], i, "vec*mat_col"); 631d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li value = create_dot_product(value, ops[0], ir->operands[1]->type->base_type, ir->operands[1]->type->vector_elements); 632d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li vector = bld.CreateInsertElement(vector, value, llvm_int(i), "vec*mat_res"); 633d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li } 634d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return vector; 635d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li } 636d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li else if (ir->operands[0]->type->is_matrix() && ir->operands[1]->type->is_matrix()) 637d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li assert(0); 638d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li 639d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li switch (ir->operands[0]->type->base_type) { 6402ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 6412ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateAnd(ops[0], ops[1]); 6422ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 6432ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 6442ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateMul(ops[0], ops[1]); 6452ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 6462ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateFMul(ops[0], ops[1]); 6472ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 6482ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 6492ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 6502ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_div: 6512ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch(ir->operands[0]->type->base_type) 6522ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 6532ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 6542ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 6552ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateUDiv(ops[0], ops[1]); 6562ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 6572ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateSDiv(ops[0], ops[1]); 6582ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 6592ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateFDiv(ops[0], ops[1]); 6602ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 6612ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 6622ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 6632ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_mod: 6642ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch(ir->operands[0]->type->base_type) 6652ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 6662ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 6672ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 6682ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateURem(ops[0], ops[1]); 6692ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 6702ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateSRem(ops[0], ops[1]); 6712ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 6722ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateFRem(ops[0], ops[1]); 6732ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 6742ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 6752ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 6762ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_less: 6772ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch(ir->operands[0]->type->base_type) 6782ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 6792ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 6802ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 6812ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateICmpULT(ops[0], ops[1]); 6822ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 6832ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateICmpSLT(ops[0], ops[1]); 6842ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 6852ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateFCmpOLT(ops[0], ops[1]); 6862ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 6872ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 6882ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 6892ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_greater: 6902ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch(ir->operands[0]->type->base_type) 6912ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 6922ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 6932ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 6942ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateICmpUGT(ops[0], ops[1]); 6952ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 6962ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateICmpSGT(ops[0], ops[1]); 6972ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 6982ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateFCmpOGT(ops[0], ops[1]); 6992ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 7002ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 7012ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 7022ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_lequal: 7032ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch(ir->operands[0]->type->base_type) 7042ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 7052ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 7062ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 7072ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateICmpULE(ops[0], ops[1]); 7082ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 7092ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateICmpSLE(ops[0], ops[1]); 7102ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 7112ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateFCmpOLE(ops[0], ops[1]); 7122ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 7132ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 7142ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 7152ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_gequal: 7162ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch(ir->operands[0]->type->base_type) 7172ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 7182ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 7192ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 7202ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateICmpUGE(ops[0], ops[1]); 7212ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 7222ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateICmpSGE(ops[0], ops[1]); 7232ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 7242ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateFCmpOGE(ops[0], ops[1]); 7252ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 7262ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 7272ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 728d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case ir_binop_equal: // fall through 729d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li case ir_binop_all_equal: // TODO: check op same as ir_binop_equal 730d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li switch (ir->operands[0]->type->base_type) { 7312ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 7322ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 7332ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 7342ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateICmpEQ(ops[0], ops[1]); 7352ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 7362ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateFCmpOEQ(ops[0], ops[1]); 7372ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 7382ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 7392ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 7402ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_nequal: 7412ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch(ir->operands[0]->type->base_type) 7422ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 7432ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 7442ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 7452ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 7462ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateICmpNE(ops[0], ops[1]); 7472ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 7482ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateFCmpONE(ops[0], ops[1]); 7492ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 7502ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 7512ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 7522ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_logic_xor: 7532ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); 7542ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateICmpNE(ops[0], ops[1]); 7552ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_logic_or: 7562ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); 7572ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateOr(ops[0], ops[1]); 7582ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_logic_and: 7592ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(ir->operands[0]->type->base_type == GLSL_TYPE_BOOL); 7602ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateAnd(ops[0], ops[1]); 7612ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_dot: 762d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return create_dot_product(ops[0], ops[1], ir->operands[0]->type->base_type, ir->operands[0]->type->vector_elements); 763d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// case ir_binop_cross: this op does not exist in ir.h 764d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// assert(ir->operands[0]->type->vector_elements == 3); 765d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// switch(ir->operands[0]->type->base_type) 766d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// { 767d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// case GLSL_TYPE_UINT: 768d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// case GLSL_TYPE_INT: 769d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// return bld.CreateSub( 770d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// bld.CreateMul(create_shuffle3(bld, ops[0], 1, 2, 0, "cross.a120"), create_shuffle3(bld, ops[1], 2, 0, 1, "cross.a201"), "cross.ab"), 771d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// bld.CreateMul(create_shuffle3(bld, ops[1], 1, 2, 0, "cross.b120"), create_shuffle3(bld, ops[0], 2, 0, 1, "cross.b201"), "cross.ba"), 772d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// "cross.sub"); 773d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// case GLSL_TYPE_FLOAT: 774d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// return bld.CreateFSub( 775d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// bld.CreateFMul(create_shuffle3(bld, ops[0], 1, 2, 0, "cross.a120"), create_shuffle3(bld, ops[1], 2, 0, 1, "cross.a201"), "cross.ab"), 776d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// bld.CreateFMul(create_shuffle3(bld, ops[1], 1, 2, 0, "cross.b120"), create_shuffle3(bld, ops[0], 2, 0, 1, "cross.b201"), "cross.ba"), 777d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// "cross.sub"); 778d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// default: 779d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// assert(0); 780d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li// } 7812ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_sqrt: 7822ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); 783d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return llvm_intrinsic_unop(ir->operation, ops[0]); 7842ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_rsq: 7852ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(ir->operands[0]->type->base_type == GLSL_TYPE_FLOAT); 786d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return bld.CreateFDiv(llvm_imm(ops[0]->getType(), 1), llvm_intrinsic_unop(ir_unop_sqrt, ops[0]), "rsqrt.rcp"); 7872ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_i2f: 7882ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateSIToFP(ops[0], llvm_type(ir->type)); 7892ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_u2f: 7902ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_b2f: 7912ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateUIToFP(ops[0], llvm_type(ir->type)); 7922ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_b2i: 7932ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateZExt(ops[0], llvm_type(ir->type)); 7942ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_f2i: 7952ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateFPToSI(ops[0], llvm_type(ir->type)); 7962ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_f2b: 7972ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateFCmpONE(ops[0], llvm_imm(ops[0]->getType(), 0)); 7982ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_i2b: 7992ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateICmpNE(ops[0], llvm_imm(ops[0]->getType(), 0)); 8002ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_trunc: 8012ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 8022ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(ir->operands[0]->type->base_type != GLSL_TYPE_FLOAT) 8032ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return ops[0]; 8042ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li glsl_type int_type = *ir->operands[0]->type; 8052ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li int_type.base_type = GLSL_TYPE_INT; 8062ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateSIToFP(bld.CreateFPToSI(ops[0], llvm_type(&int_type), "trunc.fptosi"),ops[0]->getType(), "trunc.sitofp"); 8072ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 8082ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_floor: 8092ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 8102ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(ir->operands[0]->type->base_type != GLSL_TYPE_FLOAT) 8112ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return ops[0]; 8122ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* one = llvm_imm(ops[0]->getType(), 1); 8132ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateFSub(ops[0], bld.CreateFRem(ops[0], one)); 8142ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 8152ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_ceil: 8162ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 8172ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(ir->operands[0]->type->base_type != GLSL_TYPE_FLOAT) 8182ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return ops[0]; 8192ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* one = llvm_imm(ops[0]->getType(), 1); 8202ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateFAdd(bld.CreateFSub(ops[0], bld.CreateFRem(ops[0], one)), one); 8212ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 8222ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_fract: 8232ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 8242ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(ir->operands[0]->type->base_type != GLSL_TYPE_FLOAT) 8252ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return llvm_imm(ops[0]->getType(), 0); 8262ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* one = llvm_imm(ops[0]->getType(), 1); 8272ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateFRem(ops[0], one); 8282ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 8292ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li // TODO: NaNs might be wrong in min/max, not sure how to fix it 8302ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_min: 8312ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch(ir->operands[0]->type->base_type) 8322ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 8332ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 8342ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateAnd(ops[0], ops[1], "bmin"); 8352ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 8362ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateSelect(bld.CreateICmpULE(ops[0], ops[1], "umin.le"), ops[0], ops[1], "umin.select"); 8372ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 8382ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateSelect(bld.CreateICmpSLE(ops[0], ops[1], "smin.le"), ops[0], ops[1], "smin.select"); 8392ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 8402ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateSelect(bld.CreateFCmpULE(ops[0], ops[1], "fmin.le"), ops[0], ops[1], "fmin.select"); 8412ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 8422ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 8432ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 8442ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_max: 8452ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch(ir->operands[0]->type->base_type) 8462ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 8472ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 8482ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateOr(ops[0], ops[1], "bmax"); 8492ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 8502ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateSelect(bld.CreateICmpUGE(ops[0], ops[1], "umax.ge"), ops[0], ops[1], "umax.select"); 8512ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 8522ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateSelect(bld.CreateICmpSGE(ops[0], ops[1], "smax.ge"), ops[0], ops[1], "smax.select"); 8532ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 8542ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateSelect(bld.CreateFCmpUGE(ops[0], ops[1], "fmax.ge"), ops[0], ops[1], "fmax.select"); 8552ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 8562ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 8572ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 8582ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_pow: 859d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li assert(GLSL_TYPE_FLOAT == ir->operands[0]->type->base_type); 860d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li assert(GLSL_TYPE_FLOAT == ir->operands[1]->type->base_type); 861d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return llvm_intrinsic_binop(ir_binop_pow, ops[0], ops[1]); 8622ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_unop_bit_not: 8632ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateNot(ops[0]); 8642ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_bit_and: 8652ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateAnd(ops[0], ops[1]); 8662ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_bit_xor: 8672ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateXor(ops[0], ops[1]); 8682ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_bit_or: 8692ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateOr(ops[0], ops[1]); 8702ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_lshift: 8712ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch(ir->operands[0]->type->base_type) 8722ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 8732ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 8742ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 8752ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 8762ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateLShr(ops[0], ops[1]); 8772ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 8782ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 8792ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 8802ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case ir_binop_rshift: 8812ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch(ir->operands[0]->type->base_type) 8822ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 8832ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 8842ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 8852ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateLShr(ops[0], ops[1]); 8862ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 8872ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateAShr(ops[0], ops[1]); 8882ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 8892ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 8902ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return 0; 8912ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 8922ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li default: 893d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li printf("ir->operation=%d \n", ir->operation); 8942ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(0); 8952ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return 0; 8962ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 8972ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 8982ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 8992ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li virtual void visit(class ir_expression * ir) 9002ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 9012ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li result = llvm_expression(ir); 9022ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 9032ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 9042ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li virtual void visit(class ir_dereference_array *ir) 9052ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 9062ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li result = bld.CreateLoad(llvm_pointer(ir)); 9072ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 9082ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 9092ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li virtual void visit(class ir_dereference_record *ir) 9102ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 9112ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li result = bld.CreateLoad(llvm_pointer(ir)); 9122ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 9132ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 9142ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li virtual void visit(class ir_dereference_variable *ir) 9152ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 916470970d77c095678830fc512dfe0e97c6bcab15bDavid Li result = bld.CreateLoad(llvm_pointer(ir), ir->variable_referenced()->name); 9172ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 9182ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 9192ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li virtual void visit(class ir_texture * ir) 9202ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 92113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li llvm::Value * coordinate = llvm_value(ir->coordinate); 92236ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li if (ir->projector) 92336ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li { 92436ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li llvm::Value * proj = llvm_value(ir->projector); 92536ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li unsigned width = ((llvm::VectorType*)coordinate->getType())->getNumElements(); 92636ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li llvm::Value * div = llvm::Constant::getNullValue(coordinate->getType()); 92736ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li for (unsigned i = 0; i < width; i++) 92836ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li div = bld.CreateInsertElement(div, proj, bld.getInt32(i), "texProjDup"); 92936ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li coordinate = bld.CreateFDiv(coordinate, div, "texProj"); 93036ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li } 9316426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao 93236ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li ir_variable * sampler = NULL; 93336ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li if(ir_dereference_variable* deref = ir->sampler->as_dereference_variable()) 93436ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li sampler = deref->variable_referenced(); 93536ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li else if(ir_dereference_array* deref = ir->sampler->as_dereference_array()) 93636ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li { 937b341bc8271147be311b77937347f0f3f54aab749David Li assert(0); // not implemented 93836ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li return; 93936ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li deref->array_index; 94036ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li deref->array; 94136ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li } 94236ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li else if(ir->sampler->as_dereference()) 94336ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li { 944b341bc8271147be311b77937347f0f3f54aab749David Li assert(0); // not implemented 94536ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li ir_dereference_record* deref = (ir_dereference_record*)ir->sampler; 94636ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li int idx = deref->record->type->field_index(deref->field); 94736ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li assert(idx >= 0); 94836ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li } 94936ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li else 95036ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li assert(0); 95136ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li 95236ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li assert(sampler->location >= 0 && sampler->location < 64); // TODO: proper limit 9536426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao 95436ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li // ESSL texture LOD is only for 2D texture in vert shader, and it's explicit 95536ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li // bias used only in frag shader, and added to computed LOD 95636ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li assert(ir_tex == ir->op); 9576426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao 95836ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li assert(GLSL_TYPE_FLOAT == sampler->type->sampler_type); 9596426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao printf("sampler '%s' location=%d dim=%d type=%d proj=%d lod=%d \n", sampler->name, sampler->location, 9606426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao sampler->type->sampler_dimensionality, sampler->type->sampler_type, 96136ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li ir->projector ? 1 : 0, ir->lod_info.lod ? 1 : 0); 96236ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li if (GLSL_SAMPLER_DIM_CUBE == sampler->type->sampler_dimensionality) 96336ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li result = texCube(bld, coordinate, sampler->location, gglCtx); 96436ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li else if (GLSL_SAMPLER_DIM_2D == sampler->type->sampler_dimensionality) 96536ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li result = tex2D(bld, coordinate, sampler->location, gglCtx); 9666426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao else 96736ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li assert(0); 9682ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 9692ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 9702ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li virtual void visit(class ir_discard * ir) 9712ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 9722ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::BasicBlock* discard = llvm::BasicBlock::Create(ctx, "discard", fun); 9732ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::BasicBlock* after; 9742ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(ir->condition) 9752ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 9762ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li after = llvm::BasicBlock::Create(ctx, "discard.survived", fun); 9772ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.CreateCondBr(llvm_value(ir->condition), discard, after); 9782ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 9792ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else 9802ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 9812ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li after = llvm::BasicBlock::Create(ctx, "dead_code.discard", fun); 9822ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.CreateBr(discard); 9832ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 9842ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 9852ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.SetInsertPoint(discard); 9868a0502c8141f8bed72f9da5c7ca663604a268313Logan Chien 9878a0502c8141f8bed72f9da5c7ca663604a268313Logan Chien // FIXME: According to the LLVM mailing list, UnwindInst should not 9888a0502c8141f8bed72f9da5c7ca663604a268313Logan Chien // be used by the frontend since LLVM 3.0, and 'CreateUnwind' 9898a0502c8141f8bed72f9da5c7ca663604a268313Logan Chien // method has been removed from the IRBuilder. Here's the 9908a0502c8141f8bed72f9da5c7ca663604a268313Logan Chien // temporary workaround. But it would be better to remove 9918a0502c8141f8bed72f9da5c7ca663604a268313Logan Chien // this in the future. 992c976701adf344808694880ef3a5c86133d74df2cShih-wei Liao // 993c976701adf344808694880ef3a5c86133d74df2cShih-wei Liao // A solution after LLVM 3.0: To add a global boolean in the shader to 994c976701adf344808694880ef3a5c86133d74df2cShih-wei Liao // store whether it was discarded or not and just continue on normally, 995c976701adf344808694880ef3a5c86133d74df2cShih-wei Liao // and handle the discard outside the shader, in the scanline function. 996c976701adf344808694880ef3a5c86133d74df2cShih-wei Liao // The discard instruction is not used frequently, so it should be okay 997c976701adf344808694880ef3a5c86133d74df2cShih-wei Liao // performance wise. 998c976701adf344808694880ef3a5c86133d74df2cShih-wei Liao new llvm::UnwindInst(ctx, discard); /// Deprecated 9992ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 10002ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bb = after; 10012ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.SetInsertPoint(bb); 10022ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 10032ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 10042ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li virtual void visit(class ir_loop_jump *ir) 10052ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 10062ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::BasicBlock* target; 10072ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(ir->mode == ir_loop_jump::jump_continue) 10082ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li target = loop.first; 10092ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else if(ir->mode == ir_loop_jump::jump_break) 10102ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li target = loop.second; 10112ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(target); 10122ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 10132ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.CreateBr(target); 10142ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 10152ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bb = llvm::BasicBlock::Create(ctx, "dead_code.jump", fun); 10162ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.SetInsertPoint(bb); 10172ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 10182ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 10192ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li virtual void visit(class ir_loop * ir) 10202ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 10212ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::BasicBlock* body = llvm::BasicBlock::Create(ctx, "loop", fun); 10222ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::BasicBlock* header = body; 10232ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::BasicBlock* after = llvm::BasicBlock::Create(ctx, "loop.after", fun); 10242ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* ctr; 10252ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 10262ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(ir->counter) 10272ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 10282ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li ctr = llvm_variable(ir->counter); 10292ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(ir->from) 10302ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.CreateStore(llvm_value(ir->from), ctr); 10312ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(ir->to) 10322ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li header = llvm::BasicBlock::Create(ctx, "loop.header", fun); 10332ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 10342ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 10352ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.CreateBr(header); 10362ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 10372ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(ir->counter && ir->to) 10382ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 10392ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.SetInsertPoint(header); 10402ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* cond; 10412ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* load = bld.CreateLoad(ctr); 10422ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* to = llvm_value(ir->to); 10432ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch(ir->counter->type->base_type) 10442ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 10452ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 10462ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 10472ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li cond = bld.CreateICmpULT(load, to); 10482ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li break; 10492ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 10502ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li cond = bld.CreateICmpSLT(load, to); 10512ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li break; 10522ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 10532ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li cond = bld.CreateFCmpOLT(load, to); 10542ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li break; 10552ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 10562ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.CreateCondBr(cond, body, after); 10572ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 10582ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 10592ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.SetInsertPoint(body); 10602ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 10612ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li std::pair<llvm::BasicBlock*, llvm::BasicBlock*> saved_loop = loop; 10622ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li loop = std::make_pair(header, after); 10632ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li visit_exec_list(&ir->body_instructions, this); 10642ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li loop = saved_loop; 10652ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 10662ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(ir->counter && ir->increment) 10672ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 10682ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch(ir->counter->type->base_type) 10692ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 10702ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 10712ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 10722ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 10732ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.CreateStore(bld.CreateAdd(bld.CreateLoad(ctr), llvm_value(ir->increment)), ctr); 10742ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li break; 10752ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 10762ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.CreateStore(bld.CreateFAdd(bld.CreateLoad(ctr), llvm_value(ir->increment)), ctr); 10772ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li break; 10782ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 10792ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 10802ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.CreateBr(header); 10812ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 10822ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bb = after; 10832ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.SetInsertPoint(bb); 10842ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 10852ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 10862ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li virtual void visit(class ir_if *ir) 10872ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 10882ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::BasicBlock* bbt = llvm::BasicBlock::Create(ctx, "if", fun); 10892ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::BasicBlock* bbf = llvm::BasicBlock::Create(ctx, "else", fun); 10902ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::BasicBlock* bbe = llvm::BasicBlock::Create(ctx, "endif", fun); 10912ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.CreateCondBr(llvm_value(ir->condition), bbt, bbf); 10922ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 10932ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.SetInsertPoint(bbt); 10942ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li visit_exec_list(&ir->then_instructions, this); 10952ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.CreateBr(bbe); 10962ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 10972ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.SetInsertPoint(bbf); 10982ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li visit_exec_list(&ir->else_instructions, this); 10992ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.CreateBr(bbe); 11002ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 11012ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bb = bbe; 11022ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.SetInsertPoint(bb); 11032ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 11042ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 11052ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li virtual void visit(class ir_return * ir) 11062ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 11072ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(!ir->value) 11082ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.CreateRetVoid(); 11092ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else 11102ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.CreateRet(llvm_value(ir->value)); 11112ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 11122ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bb = llvm::BasicBlock::Create(ctx, "dead_code.return", fun); 11132ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.SetInsertPoint(bb); 11142ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 11152ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 11162ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li virtual void visit(class ir_call * ir) 11172ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 11182ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li std::vector<llvm::Value*> args; 11192ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 11202ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li foreach_iter(exec_list_iterator, iter, *ir) 11212ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 11222ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li ir_rvalue *arg = (ir_constant *)iter.get(); 11232ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li args.push_back(llvm_value(arg)); 11242ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 11252ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 11260783e59a538573e2949aa558cd26e3714f9ffd7eShih-wei Liao result = bld.CreateCall(llvm_function(ir->get_callee()), llvm::ArrayRef<llvm::Value*>(args)); 11272ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 11282ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::AttrListPtr attr; 11292ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li ((llvm::CallInst*)result)->setAttributes(attr); 11302ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 11312ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 11322ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li virtual void visit(class ir_constant * ir) 11332ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 11342ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if (ir->type->base_type == GLSL_TYPE_STRUCT) { 11352ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li std::vector<llvm::Constant*> fields; 11362ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li foreach_iter(exec_list_iterator, iter, ir->components) { 11372ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li ir_constant *field = (ir_constant *)iter.get(); 11382ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li fields.push_back(llvm_constant(field)); 11392ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 11402ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li result = llvm::ConstantStruct::get((llvm::StructType*)llvm_type(ir->type), fields); 11412ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 11422ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else if (ir->type->base_type == GLSL_TYPE_ARRAY) { 11432ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li std::vector<llvm::Constant*> elems; 11442ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li for (unsigned i = 0; i < ir->type->length; i++) 11452ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li elems.push_back(llvm_constant(ir->array_elements[i])); 11462ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li result = llvm::ConstantArray::get((llvm::ArrayType*)llvm_type(ir->type), elems); 11472ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 11482ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else 11492ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 1150ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien llvm::Type* base_type = llvm_base_type(ir->type->base_type); 1151ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien llvm::Type* vec_type = llvm_vec_type(ir->type); 1152ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien llvm::Type* type = llvm_type(ir->type); 11532ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 11542ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li std::vector<llvm::Constant*> vecs; 11552ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li unsigned idx = 0; 11562ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li for (unsigned i = 0; i < ir->type->matrix_columns; ++i) { 11572ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li std::vector<llvm::Constant*> elems; 11582ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li for (unsigned j = 0; j < ir->type->vector_elements; ++j) { 11592ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Constant* elem; 11602ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li switch(ir->type->base_type) 11612ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 11622ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_FLOAT: 11632ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li elem = llvm::ConstantFP::get(base_type, ir->value.f[idx]); 11642ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li break; 11652ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_UINT: 11662ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li elem = llvm::ConstantInt::get(base_type, ir->value.u[idx]); 11672ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li break; 11682ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_INT: 11692ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li elem = llvm::ConstantInt::get(base_type, ir->value.i[idx]); 11702ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li break; 11712ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li case GLSL_TYPE_BOOL: 11722ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li elem = llvm::ConstantInt::get(base_type, ir->value.b[idx]); 11732ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li break; 11742ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 11752ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li elems.push_back(elem); 11762ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li ++idx; 11772ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 11782ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 11792ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Constant* vec; 11808159d55f69b8157c66147fa0c269d1e7c9a5e90eShih-wei Liao if(ir->type->vector_elements > 1) { 11818159d55f69b8157c66147fa0c269d1e7c9a5e90eShih-wei Liao llvm::ArrayRef<llvm::Constant*> ConstantArray(elems); 11828159d55f69b8157c66147fa0c269d1e7c9a5e90eShih-wei Liao vec = llvm::ConstantVector::get(ConstantArray); 11838159d55f69b8157c66147fa0c269d1e7c9a5e90eShih-wei Liao } else { 11842ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li vec = elems[0]; 11858159d55f69b8157c66147fa0c269d1e7c9a5e90eShih-wei Liao } 11862ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li vecs.push_back(vec); 11872ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 11882ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 11892ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(ir->type->matrix_columns > 1) 11902ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li result = llvm::ConstantArray::get((llvm::ArrayType*)type, vecs); 11912ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else 11922ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li result = vecs[0]; 11932ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 11942ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 11952ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 11962ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* llvm_shuffle(llvm::Value* val, int* shuffle_mask, unsigned res_width, const llvm::Twine &name = "") 11972ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 1198ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien llvm::Type* elem_type = val->getType(); 1199ae0c16b29d641afaff99ac106eff87fea72a23e6Logan Chien llvm::Type* res_type = elem_type;; 12002ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li unsigned val_width = 1; 12012ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(val->getType()->isVectorTy()) 12022ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 12032ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li val_width = ((llvm::VectorType*)val->getType())->getNumElements(); 12042ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li elem_type = ((llvm::VectorType*)val->getType())->getElementType(); 12052ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 12062ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(res_width > 1) 12072ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li res_type = llvm::VectorType::get(elem_type, res_width); 12082ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 12092ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Constant* shuffle_mask_values[4]; 12102ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(res_width <= 4); 12112ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bool any_def = false; 12122ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li for(unsigned i = 0; i < res_width; ++i) 12132ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 12142ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(shuffle_mask[i] < 0) 12152ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li shuffle_mask_values[i] = llvm::UndefValue::get(llvm::Type::getInt32Ty(ctx)); 12162ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else 12172ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 12182ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li any_def = true; 12192ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li shuffle_mask_values[i] = llvm_int(shuffle_mask[i]); 12202ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 12212ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 12222ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 12232ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* undef = llvm::UndefValue::get(res_type); 12242ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(!any_def) 12252ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return undef; 12262ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 12272ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(val_width > 1) 12282ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 12292ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(res_width > 1) 12302ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 12312ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(val_width == res_width) 12322ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 12332ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bool nontrivial = false; 12342ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li for(unsigned i = 0; i < val_width; ++i) 12352ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 12362ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(shuffle_mask[i] != (int)i) 12372ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li nontrivial = true; 12382ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 12392ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(!nontrivial) 12402ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return val; 12412ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 12422ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 12436730e48003ab09afe8c3c0c555ba5dee013ffc74Shih-wei Liao return bld.CreateShuffleVector(val, llvm::UndefValue::get(val->getType()), llvm::ConstantVector::get(pack(shuffle_mask_values, res_width)), name); 12442ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 12452ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else 12462ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return bld.CreateExtractElement(val, llvm_int(shuffle_mask[0]), name); 12472ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 12482ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else 12492ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 12502ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(res_width > 1) 12512ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 12522ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* tmp = undef; 12532ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li for(unsigned i = 0; i < res_width; ++i) 12542ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 12552ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(shuffle_mask[i] >= 0) 12562ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li tmp = bld.CreateInsertElement(tmp, val, llvm_int(i), name); 12572ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 12582ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return tmp; 12592ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 12602ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else if(shuffle_mask[0] >= 0) 12612ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return val; 12622ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else 12632ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return undef; 12642ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 12652ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 12662ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 12672ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 12682ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li virtual void visit(class ir_swizzle * swz) 12692ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 12702ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* val = llvm_value(swz->val); 12712ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li int mask[4] = {swz->mask.x, swz->mask.y, swz->mask.z, swz->mask.w}; 12722ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li result = llvm_shuffle(val, mask, swz->mask.num_components, "swizzle"); 12732ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 12742ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 12752ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li virtual void visit(class ir_assignment * ir) 12762ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 12772ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* lhs = llvm_pointer(ir->lhs); 12782ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Value* rhs = llvm_value(ir->rhs); 12792ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li unsigned width = ir->lhs->type->vector_elements; 12802ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li unsigned mask = (1 << width) - 1; 12812ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(rhs); 12822ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 1283d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li // TODO: masking for matrix assignment 1284d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li if (ir->rhs->type->is_matrix()) { 1285d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li bld.CreateStore(rhs, lhs, "mat_str"); 1286d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li return; 1287d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li } 1288d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li 1289d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li if (!(ir->write_mask & mask)) 12902ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return; 12912ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 129201e6ff90560d588418e706ce4d2a16d5a15520e5David Li if (ir->rhs->type->vector_elements < width) { 12932ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li int expand_mask[4] = {-1, -1, -1, -1}; 129401e6ff90560d588418e706ce4d2a16d5a15520e5David Li for (unsigned i = 0; i < ir->lhs->type->vector_elements; ++i) 12952ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li expand_mask[i] = i; 12962ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li// printf("ve: %u w %u issw: %i\n", ir->rhs->type->vector_elements, width, !!ir->rhs->as_swizzle()); 12972ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li rhs = llvm_shuffle(rhs, expand_mask, width, "assign.expand"); 12982ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 12992ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 130001e6ff90560d588418e706ce4d2a16d5a15520e5David Li if (width > 1 && (ir->write_mask & mask) != mask) { 13012ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Constant* blend_mask[4]; 130201e6ff90560d588418e706ce4d2a16d5a15520e5David Li // refer to ir.h: ir_assignment::write_mask 130301e6ff90560d588418e706ce4d2a16d5a15520e5David Li // A partially-set write mask means that each enabled channel gets 130401e6ff90560d588418e706ce4d2a16d5a15520e5David Li // the value from a consecutive channel of the rhs. 130501e6ff90560d588418e706ce4d2a16d5a15520e5David Li unsigned rhsChannel = 0; 130601e6ff90560d588418e706ce4d2a16d5a15520e5David Li for (unsigned i = 0; i < width; ++i) { 130701e6ff90560d588418e706ce4d2a16d5a15520e5David Li if (ir->write_mask & (1 << i)) 130801e6ff90560d588418e706ce4d2a16d5a15520e5David Li blend_mask[i] = llvm_int(width + rhsChannel++); 13092ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else 13102ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li blend_mask[i] = llvm_int(i); 13112ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 13126730e48003ab09afe8c3c0c555ba5dee013ffc74Shih-wei Liao rhs = bld.CreateShuffleVector(bld.CreateLoad(lhs), rhs, llvm::ConstantVector::get(pack(blend_mask, width)), "assign.writemask"); 13132ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 13142ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 13152ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(ir->condition) 13162ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li rhs = bld.CreateSelect(llvm_value(ir->condition), rhs, bld.CreateLoad(lhs), "assign.conditional"); 13172ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 13182ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.CreateStore(rhs, lhs); 13192ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 13202ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 13212ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li virtual void visit(class ir_variable * var) 13222ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 13232ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm_variable(var); 13242ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 13252ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 13262ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li virtual void visit(ir_function_signature *sig) 13272ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 13282ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(!sig->is_defined) 13292ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return; 13302ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 13312ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li assert(!fun); 13322ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li fun = llvm_function(sig); 13332ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 13342ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bb = llvm::BasicBlock::Create(ctx, "entry", fun); 13352ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.SetInsertPoint(bb); 13362ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 13372ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li llvm::Function::arg_iterator ai = fun->arg_begin(); 1338470970d77c095678830fc512dfe0e97c6bcab15bDavid Li if (!strcmp("main",sig->function_name())) 1339470970d77c095678830fc512dfe0e97c6bcab15bDavid Li { 1340470970d77c095678830fc512dfe0e97c6bcab15bDavid Li assert(3 == fun->arg_size()); 1341470970d77c095678830fc512dfe0e97c6bcab15bDavid Li bld.CreateStore(ai, inputsPtr); 1342470970d77c095678830fc512dfe0e97c6bcab15bDavid Li inputs = ai; 1343470970d77c095678830fc512dfe0e97c6bcab15bDavid Li ai++; 1344470970d77c095678830fc512dfe0e97c6bcab15bDavid Li bld.CreateStore(ai, outputsPtr); 1345470970d77c095678830fc512dfe0e97c6bcab15bDavid Li outputs = ai; 1346470970d77c095678830fc512dfe0e97c6bcab15bDavid Li ai++; 1347470970d77c095678830fc512dfe0e97c6bcab15bDavid Li bld.CreateStore(ai, constantsPtr); 1348470970d77c095678830fc512dfe0e97c6bcab15bDavid Li constants = ai; 1349470970d77c095678830fc512dfe0e97c6bcab15bDavid Li ai++; 13502ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 1351470970d77c095678830fc512dfe0e97c6bcab15bDavid Li else 1352470970d77c095678830fc512dfe0e97c6bcab15bDavid Li { 1353470970d77c095678830fc512dfe0e97c6bcab15bDavid Li foreach_iter(exec_list_iterator, iter, sig->parameters) { 1354470970d77c095678830fc512dfe0e97c6bcab15bDavid Li ir_variable* arg = (ir_variable*)iter.get(); 1355470970d77c095678830fc512dfe0e97c6bcab15bDavid Li ai->setName(arg->name); 1356470970d77c095678830fc512dfe0e97c6bcab15bDavid Li bld.CreateStore(ai, llvm_variable(arg)); 1357470970d77c095678830fc512dfe0e97c6bcab15bDavid Li ++ai; 1358470970d77c095678830fc512dfe0e97c6bcab15bDavid Li } 1359470970d77c095678830fc512dfe0e97c6bcab15bDavid Li inputs = bld.CreateLoad(inputsPtr); 1360470970d77c095678830fc512dfe0e97c6bcab15bDavid Li outputs = bld.CreateLoad(outputsPtr); 1361470970d77c095678830fc512dfe0e97c6bcab15bDavid Li constants = bld.CreateLoad(constantsPtr); 1362470970d77c095678830fc512dfe0e97c6bcab15bDavid Li } 1363470970d77c095678830fc512dfe0e97c6bcab15bDavid Li inputs->setName("gl_inputs"); 1364470970d77c095678830fc512dfe0e97c6bcab15bDavid Li outputs->setName("gl_outputs"); 1365470970d77c095678830fc512dfe0e97c6bcab15bDavid Li constants->setName("gl_constants"); 13666426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao 13676426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liao 13682ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 13692ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li foreach_iter(exec_list_iterator, iter, sig->body) { 13702ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li ir_instruction *ir = (ir_instruction *)iter.get(); 13712ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 13722ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li ir->accept(this); 13732ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 13742ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 13752ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(fun->getReturnType()->isVoidTy()) 13762ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.CreateRetVoid(); 13772ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li else 13782ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bld.CreateRet(llvm::UndefValue::get(fun->getReturnType())); 13792ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 13802ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li bb = NULL; 13812ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li fun = NULL; 13822ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 13832ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 13842ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li virtual void visit(class ir_function * funs) 13852ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 13862ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li foreach_iter(exec_list_iterator, iter, *funs) 13872ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 13882ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li ir_function_signature* sig = (ir_function_signature*)iter.get(); 13892ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li sig->accept(this); 13902ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 13912ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 13922ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li}; 13932ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 13942ccfc245453738134c327ebd5f5dd189a7a6184bDavid Listruct llvm::Module * 13956426f20049f52144c8b28aaf4a1770fecead5921Shih-wei Liaoglsl_ir_to_llvm_module(struct exec_list *ir, llvm::Module * mod, 13962ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li const struct GGLState * gglCtx, const char * shaderSuffix) 13972ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li{ 1398e82376d380005c21cb70637d42104fcd4d652843David Li ir_to_llvm_visitor v(mod, gglCtx, shaderSuffix); 13992ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 14002ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li visit_exec_list(ir, &v); 14012ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 14022ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li// mod->dump(); 14032ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li if(llvm::verifyModule(*mod, llvm::PrintMessageAction, 0)) 14042ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li { 1405470970d77c095678830fc512dfe0e97c6bcab15bDavid Li puts("**\n module verification failed **\n"); 1406470970d77c095678830fc512dfe0e97c6bcab15bDavid Li mod->dump(); 1407d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li assert(0); 1408e82376d380005c21cb70637d42104fcd4d652843David Li return NULL; 14092ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li } 14102ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li 14112ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li return mod; 14122ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li //v.ir_to_llvm_emit_op1(NULL, OPCODE_END, ir_to_llvm_undef_dst, ir_to_llvm_undef); 14132ccfc245453738134c327ebd5f5dd189a7a6184bDavid Li} 1414