summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/gallivm/instructionssoa.cpp
blob: a4d50466373c7e6a12d69065b507c1a59414ecc7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include "instructionssoa.h"

#include "storagesoa.h"

#include <llvm/Constants.h>

using namespace llvm;

InstructionsSoa::InstructionsSoa(llvm::Module *mod, llvm::Function *func,
                                 llvm::BasicBlock *block, StorageSoa *storage)
   : m_builder(block),
     m_storage(storage),
     m_idx(0)
{
}

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

llvm::Value * InstructionsSoa::vectorFromVals(llvm::Value *x, llvm::Value *y,
                                              llvm::Value *z, llvm::Value *w)
{
   VectorType  *vectorType = VectorType::get(Type::FloatTy, 4);
   Constant *constVector = Constant::getNullValue(vectorType);
   Value *res = m_builder.CreateInsertElement(constVector, x,
                                              m_storage->constantInt(0),
                                              name("vecx"));
   res = m_builder.CreateInsertElement(res, y, m_storage->constantInt(1),
                               name("vecxy"));
   res = m_builder.CreateInsertElement(res, z, m_storage->constantInt(2),
                               name("vecxyz"));
   if (w)
      res = m_builder.CreateInsertElement(res, w, m_storage->constantInt(3),
                                          name("vecxyzw"));
   return res;
}

std::vector<llvm::Value*> InstructionsSoa::arl(const std::vector<llvm::Value*> in)
{
   std::vector<llvm::Value*> res(4);

   //Extract x's
   llvm::Value *x1 = m_builder.CreateExtractElement(in[0],
                                                    m_storage->constantInt(0),
                                                    name("extractX"));
   //cast it to an unsigned int
   x1 = m_builder.CreateFPToUI(x1, IntegerType::get(32), name("x1IntCast"));

   res[0] = x1;//vectorFromVals(x1, x2, x3, x4);
   //only x is valid. the others shouldn't be necessary
   /*
   res[1] = Constant::getNullValue(m_floatVecType);
   res[2] = Constant::getNullValue(m_floatVecType);
   res[3] = Constant::getNullValue(m_floatVecType);
   */

   return res;
}


std::vector<llvm::Value*> InstructionsSoa::add(const std::vector<llvm::Value*> in1,
                                               const std::vector<llvm::Value*> in2)
{
   std::vector<llvm::Value*> res(4);

   res[0] = m_builder.CreateAdd(in1[0], in2[0], name("addx"));
   res[1] = m_builder.CreateAdd(in1[1], in2[1], name("addy"));
   res[2] = m_builder.CreateAdd(in1[2], in2[2], name("addz"));
   res[3] = m_builder.CreateAdd(in1[3], in2[3], name("addw"));

   return res;
}

std::vector<llvm::Value*> InstructionsSoa::mul(const std::vector<llvm::Value*> in1,
                                               const std::vector<llvm::Value*> in2)
{
   std::vector<llvm::Value*> res(4);

   res[0] = m_builder.CreateMul(in1[0], in2[0], name("mulx"));
   res[1] = m_builder.CreateMul(in1[1], in2[1], name("muly"));
   res[2] = m_builder.CreateMul(in1[2], in2[2], name("mulz"));
   res[3] = m_builder.CreateMul(in1[3], in2[3], name("mulw"));

   return res;
}

void InstructionsSoa::end()
{
   m_builder.CreateRetVoid();
}

std::vector<llvm::Value*> InstructionsSoa::madd(const std::vector<llvm::Value*> in1,
                                                const std::vector<llvm::Value*> in2,
                                                const std::vector<llvm::Value*> in3)
{
   std::vector<llvm::Value*> res = mul(in1, in2);
   return add(res, in3);
}

std::vector<llvm::Value*> InstructionsSoa::extractVector(llvm::Value *vector)
{
   std::vector<llvm::Value*> res(4);
   res[0] = m_builder.CreateExtractElement(vector,
                                           m_storage->constantInt(0),
                                           name("extract1X"));
   res[1] = m_builder.CreateExtractElement(vector,
                                           m_storage->constantInt(1),
                                           name("extract2X"));
   res[2] = m_builder.CreateExtractElement(vector,
                                           m_storage->constantInt(2),
                                           name("extract3X"));
   res[3] = m_builder.CreateExtractElement(vector,
                                           m_storage->constantInt(3),
                                           name("extract4X"));

   return res;
}