Zack Rusin | b0f8069 | 2007-10-17 11:28:26 -0400 | [diff] [blame^] | 1 | #include "storage.h" |
Zack Rusin | fa2962d | 2007-10-16 13:23:43 -0400 | [diff] [blame] | 2 | |
Zack Rusin | b0f8069 | 2007-10-17 11:28:26 -0400 | [diff] [blame^] | 3 | #include <llvm/BasicBlock.h> |
| 4 | #include <llvm/Module.h> |
| 5 | #include <llvm/Value.h> |
Zack Rusin | fa2962d | 2007-10-16 13:23:43 -0400 | [diff] [blame] | 6 | |
Zack Rusin | b0f8069 | 2007-10-17 11:28:26 -0400 | [diff] [blame^] | 7 | #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 Rusin | fa2962d | 2007-10-16 13:23:43 -0400 | [diff] [blame] | 12 | |
Zack Rusin | b0f8069 | 2007-10-17 11:28:26 -0400 | [diff] [blame^] | 13 | using namespace llvm; |
Zack Rusin | fa2962d | 2007-10-16 13:23:43 -0400 | [diff] [blame] | 14 | |
Zack Rusin | 3975f34 | 2007-10-17 11:27:46 -0400 | [diff] [blame] | 15 | Storage::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 Rusin | fa2962d | 2007-10-16 13:23:43 -0400 | [diff] [blame] | 20 | { |
| 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 Rusin | 3975f34 | 2007-10-17 11:27:46 -0400 | [diff] [blame] | 31 | llvm::Constant *Storage::shuffleMask(int vec) |
Zack Rusin | fa2962d | 2007-10-16 13:23:43 -0400 | [diff] [blame] | 32 | { |
| 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 Rusin | 3975f34 | 2007-10-17 11:27:46 -0400 | [diff] [blame] | 57 | llvm::ConstantInt *Storage::constantInt(int idx) |
Zack Rusin | fa2962d | 2007-10-16 13:23:43 -0400 | [diff] [blame] | 58 | { |
| 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 Rusin | 3975f34 | 2007-10-17 11:27:46 -0400 | [diff] [blame] | 67 | llvm::Value *Storage::inputElement(int idx) |
Zack Rusin | fa2962d | 2007-10-16 13:23:43 -0400 | [diff] [blame] | 68 | { |
| 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 Rusin | 3975f34 | 2007-10-17 11:27:46 -0400 | [diff] [blame] | 86 | llvm::Value *Storage::constElement(int idx) |
Zack Rusin | fa2962d | 2007-10-16 13:23:43 -0400 | [diff] [blame] | 87 | { |
| 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 Rusin | 3975f34 | 2007-10-17 11:27:46 -0400 | [diff] [blame] | 105 | llvm::Value *Storage::shuffleVector(llvm::Value *vec, int shuffle) |
Zack Rusin | fa2962d | 2007-10-16 13:23:43 -0400 | [diff] [blame] | 106 | { |
| 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 Rusin | 3975f34 | 2007-10-17 11:27:46 -0400 | [diff] [blame] | 116 | |
| 117 | |
| 118 | llvm::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 | |
| 126 | void Storage::setTempElement(int idx, llvm::Value *val) |
| 127 | { |
| 128 | m_temps[idx] = val; |
| 129 | } |
| 130 | |
| 131 | void 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 | } |