blob: c6e86ea4b434aa33324fcf4e83cdce40673eab40 [file] [log] [blame]
Zack Rusinb0f80692007-10-17 11:28:26 -04001#include "storage.h"
Zack Rusinfa2962d2007-10-16 13:23:43 -04002
Zack Rusinb0f80692007-10-17 11:28:26 -04003#include <llvm/BasicBlock.h>
4#include <llvm/Module.h>
5#include <llvm/Value.h>
Zack Rusinfa2962d2007-10-16 13:23:43 -04006
Zack Rusinb0f80692007-10-17 11:28:26 -04007#include <llvm/CallingConv.h>
8#include <llvm/Constants.h>
9#include <llvm/DerivedTypes.h>
10#include <llvm/InstrTypes.h>
11#include <llvm/Instructions.h>
Zack Rusinfa2962d2007-10-16 13:23:43 -040012
Zack Rusinb0f80692007-10-17 11:28:26 -040013using namespace llvm;
Zack Rusinfa2962d2007-10-16 13:23:43 -040014
Zack Rusin3975f342007-10-17 11:27:46 -040015Storage::Storage(llvm::BasicBlock *block, llvm::Value *out,
16 llvm::Value *in, llvm::Value *consts)
17 : m_block(block), m_OUT(out),
18 m_IN(in), m_CONST(consts),
19 m_temps(32)
Zack Rusinfa2962d2007-10-16 13:23:43 -040020{
21 m_floatVecType = VectorType::get(Type::FloatTy, 4);
22 m_intVecType = VectorType::get(IntegerType::get(32), 4);
23
24 m_undefFloatVec = UndefValue::get(m_floatVecType);
25 m_undefIntVec = UndefValue::get(m_intVecType);
26
27 m_shuffleId = 0;
28}
29
30//can only build vectors with all members in the [0, 9] range
Zack Rusin3975f342007-10-17 11:27:46 -040031llvm::Constant *Storage::shuffleMask(int vec)
Zack Rusinfa2962d2007-10-16 13:23:43 -040032{
33 if (m_intVecs.find(vec) != m_intVecs.end()) {
34 return m_intVecs[vec];
35 }
36 int origVec = vec;
37 Constant* const_vec = 0;
38 if (origVec == 0) {
39 const_vec = Constant::getNullValue(m_intVecType);
40 } else {
41 int x = vec / 1000; vec -= x * 1000;
42 int y = vec / 100; vec -= y * 100;
43 int z = vec / 10; vec -= z * 10;
44 int w = vec;
45 std::vector<Constant*> elems;
46 elems.push_back(constantInt(x));
47 elems.push_back(constantInt(y));
48 elems.push_back(constantInt(z));
49 elems.push_back(constantInt(w));
50 const_vec = ConstantVector::get(m_intVecType, elems);
51 }
52
53 m_intVecs[origVec] = const_vec;
54 return const_vec;
55}
56
Zack Rusin3975f342007-10-17 11:27:46 -040057llvm::ConstantInt *Storage::constantInt(int idx)
Zack Rusinfa2962d2007-10-16 13:23:43 -040058{
59 if (m_constInts.find(idx) != m_constInts.end()) {
60 return m_constInts[idx];
61 }
62 ConstantInt *const_int = ConstantInt::get(APInt(32, idx));
63 m_constInts[idx] = const_int;
64 return const_int;
65}
66
Zack Rusin3975f342007-10-17 11:27:46 -040067llvm::Value *Storage::inputElement(int idx)
Zack Rusinfa2962d2007-10-16 13:23:43 -040068{
69 if (m_inputs.find(idx) != m_inputs.end()) {
70 return m_inputs[idx];
71 }
72 char ptrName[13];
73 char name[9];
74 snprintf(ptrName, 13, "input_ptr%d", idx);
75 snprintf(name, 9, "input%d", idx);
76 GetElementPtrInst *getElem = new GetElementPtrInst(m_IN,
77 constantInt(idx),
78 ptrName,
79 m_block);
80 LoadInst *load = new LoadInst(getElem, name,
81 false, m_block);
82 m_inputs[idx] = load;
83 return load;
84}
85
Zack Rusin3975f342007-10-17 11:27:46 -040086llvm::Value *Storage::constElement(int idx)
Zack Rusinfa2962d2007-10-16 13:23:43 -040087{
88 if (m_consts.find(idx) != m_consts.end()) {
89 return m_consts[idx];
90 }
91 char ptrName[13];
92 char name[9];
93 snprintf(ptrName, 13, "const_ptr%d", idx);
94 snprintf(name, 9, "const%d", idx);
95 GetElementPtrInst *getElem = new GetElementPtrInst(m_CONST,
96 constantInt(idx),
97 ptrName,
98 m_block);
99 LoadInst *load = new LoadInst(getElem, name,
100 false, m_block);
101 m_consts[idx] = load;
102 return load;
103}
104
Zack Rusin3975f342007-10-17 11:27:46 -0400105llvm::Value *Storage::shuffleVector(llvm::Value *vec, int shuffle)
Zack Rusinfa2962d2007-10-16 13:23:43 -0400106{
107 Constant *mask = shuffleMask(shuffle);
108 ++m_shuffleId;
109 char name[11];
110 snprintf(name, 11, "shuffle%d", m_shuffleId);
111 ShuffleVectorInst *res =
112 new ShuffleVectorInst(vec, m_undefFloatVec, mask,
113 name, m_block);
114 return res;
115}
Zack Rusin3975f342007-10-17 11:27:46 -0400116
117
118llvm::Value *Storage::tempElement(int idx) const
119{
120 Value *ret = m_temps[idx];
121 if (!ret)
122 return m_undefFloatVec;
123 return ret;
124}
125
126void Storage::setTempElement(int idx, llvm::Value *val)
127{
128 m_temps[idx] = val;
129}
130
131void Storage::store(int dstIdx, llvm::Value *val)
132{
133 char ptrName[13];
134 snprintf(ptrName, 13, "out_ptr%d", dstIdx);
135 GetElementPtrInst *getElem = new GetElementPtrInst(m_OUT,
136 constantInt(dstIdx),
137 ptrName,
138 m_block);
139 new StoreInst(val, getElem, false, m_block);
140}