/**************************************************************************
 *
 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 **************************************************************************/

 /*
  * Authors:
  *   Zack Rusin zack@tungstengraphics.com
  */
#ifdef MESA_LLVM

#include "storage.h"

#include "gallivm_p.h"

#include "pipe/p_shader_tokens.h"
#include <llvm/BasicBlock.h>
#include <llvm/Module.h>
#include <llvm/Value.h>

#include <llvm/CallingConv.h>
#include <llvm/Constants.h>
#include <llvm/DerivedTypes.h>
#include <llvm/InstrTypes.h>
#include <llvm/Instructions.h>

using namespace llvm;

Storage::Storage(llvm::BasicBlock *block, llvm::Value *input)
   : m_block(block),
     m_INPUT(input),
     m_addrs(32),
     m_idx(0)
{
   m_floatVecType = VectorType::get(Type::FloatTy, 4);
   m_intVecType   = VectorType::get(IntegerType::get(32), 4);

   m_undefFloatVec = UndefValue::get(m_floatVecType);
   m_undefIntVec   = UndefValue::get(m_intVecType);
   m_extSwizzleVec = 0;

   m_numConsts = 0;
}

//can only build vectors with all members in the [0, 9] range
llvm::Constant *Storage::shuffleMask(int vec)
{
   if (!m_extSwizzleVec) {
      std::vector<Constant*> elems;
      elems.push_back(ConstantFP::get(APFloat(0.f)));
      elems.push_back(ConstantFP::get(APFloat(1.f)));
      elems.push_back(ConstantFP::get(APFloat(0.f)));
      elems.push_back(ConstantFP::get(APFloat(1.f)));
      m_extSwizzleVec = ConstantVector::get(m_floatVecType, elems);
   }

   if (m_intVecs.find(vec) != m_intVecs.end()) {
      return m_intVecs[vec];
   }
   int origVec = vec;
   Constant* const_vec = 0;
   if (origVec == 0) {
      const_vec = Constant::getNullValue(m_intVecType);
   } else {
      int x = gallivm_x_swizzle(vec);
      int y = gallivm_y_swizzle(vec);
      int z = gallivm_z_swizzle(vec);
      int w = gallivm_w_swizzle(vec);
      std::vector<Constant*> elems;
      elems.push_back(constantInt(x));
      elems.push_back(constantInt(y));
      elems.push_back(constantInt(z));
      elems.push_back(constantInt(w));
      const_vec = ConstantVector::get(m_intVecType, elems);
   }

   m_intVecs[origVec] = const_vec;
   return const_vec;
}

llvm::ConstantInt *Storage::constantInt(int idx)
{
   if (m_constInts.find(idx) != m_constInts.end()) {
      return m_constInts[idx];
   }
   ConstantInt *const_int = ConstantInt::get(APInt(32,  idx));
   m_constInts[idx] = const_int;
   return const_int;
}

llvm::Value *Storage::inputElement(int idx, llvm::Value *indIdx)
{
   Value *val = element(InputsArg, idx, indIdx);
   LoadInst *load = new LoadInst(val, name("input"), false, m_block);
   load->setAlignment(8);

   return load;
}

llvm::Value *Storage::constElement(int idx, llvm::Value *indIdx)
{
   m_numConsts = ((idx + 1) > m_numConsts) ? (idx + 1) : m_numConsts;

   Value *elem = element(ConstsArg, idx, indIdx);
   LoadInst *load = new LoadInst(elem, name("const"), false, m_block);
   load->setAlignment(8);
   return load;
}

llvm::Value *Storage::shuffleVector(llvm::Value *vec, int shuffle)
{
   Constant *mask = shuffleMask(shuffle);
   ShuffleVectorInst *res =
      new ShuffleVectorInst(vec, m_extSwizzleVec, mask,
                            name("shuffle"), m_block);
   return res;
}


llvm::Value *Storage::tempElement(int idx, llvm::Value *indIdx)
{
   Value *elem = element(TempsArg, idx, indIdx);

   LoadInst *load = new LoadInst(elem, name("temp"), false, m_block);
   load->setAlignment(8);

   return load;
}

void Storage::setTempElement(int idx, llvm::Value *val, int mask)
{
   if (mask != TGSI_WRITEMASK_XYZW) {
      llvm::Value *templ = 0;
      if (m_tempWriteMap[idx])
         templ = tempElement(idx);
      val = maskWrite(val, mask, templ);
   }
   Value *elem = element(TempsArg, idx);
   StoreInst *st = new StoreInst(val, elem, false, m_block);
   st->setAlignment(8);
   m_tempWriteMap[idx] = true;
}

void Storage::setOutputElement(int dstIdx, llvm::Value *val, int mask)
{
   if (mask != TGSI_WRITEMASK_XYZW) {
      llvm::Value *templ = 0;
      if (m_destWriteMap[dstIdx])
         templ = outputElement(dstIdx);
      val = maskWrite(val, mask, templ);
   }

   Value *elem = element(DestsArg, dstIdx);
   StoreInst *st = new StoreInst(val, elem, false, m_block);
   st->setAlignment(8);
   m_destWriteMap[dstIdx] = true;
}

llvm::Value *Storage::maskWrite(llvm::Value *src, int mask, llvm::Value *templ)
{
   llvm::Value *dst = templ;
   if (!dst)
      dst = Constant::getNullValue(m_floatVecType);
   if ((mask & TGSI_WRITEMASK_X)) {
      llvm::Value *x = new ExtractElementInst(src, unsigned(0),
                                              name("x"), m_block);
      dst = InsertElementInst::Create(dst, x, unsigned(0),
                                      name("dstx"), m_block);
   }
   if ((mask & TGSI_WRITEMASK_Y)) {
      llvm::Value *y = new ExtractElementInst(src, unsigned(1),
                                              name("y"), m_block);
      dst = InsertElementInst::Create(dst, y, unsigned(1),
                                      name("dsty"), m_block);
   }
   if ((mask & TGSI_WRITEMASK_Z)) {
      llvm::Value *z = new ExtractElementInst(src, unsigned(2),
                                              name("z"), m_block);
      dst = InsertElementInst::Create(dst, z, unsigned(2),
                                      name("dstz"), m_block);
   }
   if ((mask & TGSI_WRITEMASK_W)) {
      llvm::Value *w = new ExtractElementInst(src, unsigned(3),
                                              name("w"), m_block);
      dst = InsertElementInst::Create(dst, w, unsigned(3),
                                      name("dstw"), m_block);
   }
   return dst;
}

const char * Storage::name(const char *prefix)
{
   ++m_idx;
   snprintf(m_name, 32, "%s%d", prefix, m_idx);
   return m_name;
}

int Storage::numConsts() const
{
   return m_numConsts;
}

llvm::Value * Storage::addrElement(int idx) const
{
   Value *ret = m_addrs[idx];
   if (!ret)
      return m_undefFloatVec;
   return ret;
}

void Storage::setAddrElement(int idx, llvm::Value *val, int mask)
{
   if (mask != TGSI_WRITEMASK_XYZW) {
      llvm::Value *templ = m_addrs[idx];
      val = maskWrite(val, mask, templ);
   }
   m_addrs[idx] = val;
}

llvm::Value * Storage::extractIndex(llvm::Value *vec)
{
   llvm::Value *x = new ExtractElementInst(vec, unsigned(0),
                                           name("x"), m_block);
   return new FPToSIInst(x, IntegerType::get(32), name("intidx"), m_block);
}

void Storage::setCurrentBlock(llvm::BasicBlock *block)
{
   m_block = block;
}

llvm::Value * Storage::outputElement(int idx, llvm::Value *indIdx)
{
   Value *elem = element(DestsArg, idx, indIdx);
   LoadInst *load = new LoadInst(elem, name("output"), false, m_block);
   load->setAlignment(8);

   return load;
}

llvm::Value * Storage::inputPtr() const
{
   return m_INPUT;
}

void Storage::pushArguments(llvm::Value *input)
{
   m_argStack.push(m_INPUT);

   m_INPUT = input;
}

void Storage::popArguments()
{
   m_INPUT = m_argStack.top();
   m_argStack.pop();
}

void Storage::pushTemps()
{
   m_extSwizzleVec = 0;
}

void Storage::popTemps()
{
}

llvm::Value * Storage::immediateElement(int idx)
{
   return m_immediates[idx];
}

void Storage::addImmediate(float *val)
{
   std::vector<Constant*> vec(4);
   vec[0] = ConstantFP::get(APFloat(val[0]));
   vec[1] = ConstantFP::get(APFloat(val[1]));
   vec[2] = ConstantFP::get(APFloat(val[2]));
   vec[3] = ConstantFP::get(APFloat(val[3]));
   m_immediates.push_back(ConstantVector::get(m_floatVecType, vec));
}


llvm::Value * Storage::elemPtr(Args arg)
{
   std::vector<Value*> indices;
   indices.push_back(constantInt(0));
   indices.push_back(constantInt(static_cast<int>(arg)));
   GetElementPtrInst *getElem = GetElementPtrInst::Create(m_INPUT,
                                                          indices.begin(),
                                                          indices.end(),
                                                          name("input_ptr"),
                                                          m_block);
   return new LoadInst(getElem, name("input_field"), false, m_block);
}

llvm::Value * Storage::elemIdx(llvm::Value *ptr, int idx,
                               llvm::Value *indIdx )
{
   GetElementPtrInst *getElem = 0;

   if (indIdx) {
      getElem = GetElementPtrInst::Create(ptr,
                                      BinaryOperator::Create(Instruction::Add,
                                                             indIdx,
                                                             constantInt(idx),
                                                             name("add"),
                                                             m_block),
                                      name("field"),
                                      m_block);
   } else {
      getElem = GetElementPtrInst::Create(ptr,
                                      constantInt(idx),
                                      name("field"),
                                      m_block);
   }
   return getElem;
}

llvm::Value * Storage::element(Args arg, int idx, llvm::Value *indIdx )
{
   Value *val = elemPtr(arg);
   return elemIdx(val, idx, indIdx);
}

void Storage::setKilElement(llvm::Value *val)
{
   std::vector<Value*> indices;
   indices.push_back(constantInt(0));
   indices.push_back(constantInt(static_cast<int>(KilArg)));
   GetElementPtrInst *elem = GetElementPtrInst::Create(m_INPUT,
                                                   indices.begin(),
                                                   indices.end(),
                                                   name("kil_ptr"),
                                                   m_block);
   StoreInst *st = new StoreInst(val, elem, false, m_block);
   st->setAlignment(8);
}

#endif //MESA_LLVM


