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