source: icGREP/icgrep-devel/icgrep/IDISA/idisa_builder.cpp @ 4843

Last change on this file since 4843 was 4843, checked in by cameron, 4 years ago

Move genPrintRegister into IDISA builder; fix GCB defs

File size: 8.8 KB
Line 
1/*
2 *  Copyright (c) 2015 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#include "idisa_builder.h"
8#include <llvm/IR/IRBuilder.h>
9#include <llvm/IR/Constants.h>
10#include <llvm/IR/Intrinsics.h>
11#include <llvm/IR/Function.h>
12
13namespace IDISA {
14
15Value * IDISA_Builder::bitBlockCast(Value * a) {
16    return a->getType() == mBitBlockType ? a : mLLVMBuilder->CreateBitCast(a, mBitBlockType);
17}
18
19VectorType * IDISA_Builder::fwVectorType(unsigned fw) {
20    int fieldCount = mBitBlockWidth/fw;
21    return VectorType::get(mLLVMBuilder->getIntNTy(fw), fieldCount);
22}
23
24Value * IDISA_Builder::fwCast(unsigned fw, Value * a) {
25    return a->getType() == fwVectorType(fw) ? a : mLLVMBuilder->CreateBitCast(a, fwVectorType(fw));
26}
27
28void IDISA_Builder::genPrintRegister(std::string regName, Value * bitblockValue) {
29    if (mPrintRegisterFunction == nullptr) {
30        mPrintRegisterFunction = mMod->getOrInsertFunction("wrapped_print_register", Type::getVoidTy(mMod->getContext()), Type::getInt8PtrTy(mMod->getContext()), mBitBlockType, NULL);
31    }
32    Constant * regNameData = ConstantDataArray::getString(mMod->getContext(), regName);
33    GlobalVariable *regStrVar = new GlobalVariable(*mMod,
34                                                   ArrayType::get(IntegerType::get(mMod->getContext(), 8), regName.length()+1),
35                                                   /*isConstant=*/ true,
36                                                   /*Linkage=*/ GlobalValue::PrivateLinkage,
37                                                   /*Initializer=*/ regNameData);
38    Value * regStrPtr = mLLVMBuilder->CreateGEP(regStrVar, std::vector<Value *>({mLLVMBuilder->getInt64(0), mLLVMBuilder->getInt32(0)}));
39    mLLVMBuilder->CreateCall(mPrintRegisterFunction, std::vector<Value *>({regStrPtr, bitblockValue}));
40}
41
42   
43Value * IDISA_Builder::simd_add(unsigned fw, Value * a, Value * b) {
44    return mLLVMBuilder->CreateAdd(fwCast(fw, a), fwCast(fw, b));
45}
46
47Value * IDISA_Builder::simd_sub(unsigned fw, Value * a, Value * b) {
48    return mLLVMBuilder->CreateSub(fwCast(fw, a), fwCast(fw, b));
49}
50
51Value * IDISA_Builder::simd_mult(unsigned fw, Value * a, Value * b) {
52    return mLLVMBuilder->CreateMul(fwCast(fw, a), fwCast(fw, b));
53}
54
55Value * IDISA_Builder::simd_eq(unsigned fw, Value * a, Value * b) {
56    return mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpEQ(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw));
57}
58
59Value * IDISA_Builder::simd_gt(unsigned fw, Value * a, Value * b) {
60    return mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpSGT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw));
61}
62
63Value * IDISA_Builder::simd_ugt(unsigned fw, Value * a, Value * b) {
64    return mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpUGT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw));
65}
66
67Value * IDISA_Builder::simd_lt(unsigned fw, Value * a, Value * b) {
68    return mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpSLT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw));
69}
70
71Value * IDISA_Builder::simd_ult(unsigned fw, Value * a, Value * b) {
72    return mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpULT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw));
73}
74
75Value * IDISA_Builder::simd_max(unsigned fw, Value * a, Value * b) {
76    Value * aVec = fwCast(fw, a);
77    Value * bVec = fwCast(fw, b);
78    return mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpSGT(aVec, bVec), aVec, bVec);
79}
80
81Value * IDISA_Builder::simd_umax(unsigned fw, Value * a, Value * b) {
82    Value * aVec = fwCast(fw, a);
83    Value * bVec = fwCast(fw, b);
84    return mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpUGT(aVec, bVec), aVec, bVec);
85}
86
87Value * IDISA_Builder::simd_min(unsigned fw, Value * a, Value * b) {
88    Value * aVec = fwCast(fw, a);
89    Value * bVec = fwCast(fw, b);
90    return mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpSLT(aVec, bVec), aVec, bVec);
91}
92
93Value * IDISA_Builder::simd_umin(unsigned fw, Value * a, Value * b) {
94    Value * aVec = fwCast(fw, a);
95    Value * bVec = fwCast(fw, b);
96    return mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpULT(aVec, bVec), aVec, bVec);
97}
98
99Value * IDISA_Builder::simd_slli(unsigned fw, Value * a, unsigned shift) {
100    return mLLVMBuilder->CreateShl(fwCast(fw, a), shift);
101}
102
103Value * IDISA_Builder::simd_srli(unsigned fw, Value * a, unsigned shift) {
104    return mLLVMBuilder->CreateLShr(fwCast(fw, a), shift);
105}
106
107Value * IDISA_Builder::simd_srai(unsigned fw, Value * a, unsigned shift) {
108    return mLLVMBuilder->CreateAShr(fwCast(fw, a), shift);
109}
110
111Value * IDISA_Builder::simd_cttz(unsigned fw, Value * a) {
112    Value * cttzFunc = Intrinsic::getDeclaration(mMod, Intrinsic::cttz, fwVectorType(fw));
113    Value * rslt = mLLVMBuilder->CreateCall(cttzFunc, std::vector<Value *>({fwCast(fw, a), ConstantInt::get(mLLVMBuilder->getInt1Ty(), 0)}));
114    return rslt;
115}
116
117Value * IDISA_Builder::simd_popcount(unsigned fw, Value * a) {
118    Value * ctpopFunc = Intrinsic::getDeclaration(mMod, Intrinsic::ctpop, fwVectorType(fw));
119    Value * rslt = mLLVMBuilder->CreateCall(ctpopFunc, std::vector<Value *>({fwCast(fw, a)}));
120    return rslt;
121}
122
123Value * IDISA_Builder::esimd_mergeh(unsigned fw, Value * a, Value * b) {
124    unsigned field_count = mBitBlockWidth/fw;
125    Value * aVec = fwCast(fw, a);
126    Value * bVec = fwCast(fw, b);
127    std::vector<Constant*> Idxs;
128    for (unsigned i = field_count/2; i < field_count; i++) {
129        Idxs.push_back(mLLVMBuilder->getInt32(i));    // selects elements from first reg.
130        Idxs.push_back(mLLVMBuilder->getInt32(i + field_count)); // selects elements from second reg.
131    }
132    return mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs));
133}
134
135Value * IDISA_Builder::esimd_mergel(unsigned fw, Value * a, Value * b) {
136    unsigned field_count = mBitBlockWidth/fw;
137    Value * aVec = fwCast(fw, a);
138    Value * bVec = fwCast(fw, b);
139    std::vector<Constant*> Idxs;
140    for (unsigned i = 0; i < field_count/2; i++) {
141        Idxs.push_back(mLLVMBuilder->getInt32(i));    // selects elements from first reg.
142        Idxs.push_back(mLLVMBuilder->getInt32(i + field_count)); // selects elements from second reg.
143    }
144    return mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs));
145}
146
147Value * IDISA_Builder::hsimd_packh(unsigned fw, Value * a, Value * b) {
148    unsigned field_count = 2 * mBitBlockWidth/fw;
149    Value * aVec = fwCast(fw/2, a);
150    Value * bVec = fwCast(fw/2, b);
151    std::vector<Constant*> Idxs;
152    for (unsigned i = 0; i < field_count; i++) {
153        Idxs.push_back(mLLVMBuilder->getInt32(2*i));
154    }
155    return mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs));
156}
157
158Value * IDISA_Builder::hsimd_packl(unsigned fw, Value * a, Value * b) {
159    unsigned field_count = 2 * mBitBlockWidth/fw;
160    Value * aVec = fwCast(fw/2, a);
161    Value * bVec = fwCast(fw/2, b);
162    std::vector<Constant*> Idxs;
163    for (unsigned i = 0; i < field_count; i++) {
164        Idxs.push_back(mLLVMBuilder->getInt32(2*i+1));
165    }
166    return mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs));
167}
168
169Value * IDISA_Builder::hsimd_signmask(unsigned fw, Value * a) {
170    Value * mask = mLLVMBuilder->CreateICmpSLT(fwCast(fw, a), ConstantAggregateZero::get(fwVectorType(fw)));
171    return mLLVMBuilder->CreateBitCast(mask, mLLVMBuilder->getIntNTy(mBitBlockWidth/fw));
172}
173
174Value * IDISA_Builder::mvmd_extract(unsigned fw, Value * a, unsigned fieldIndex) {
175    Value * aVec = fwCast(fw, a);
176    return mLLVMBuilder->CreateExtractElement(aVec, mLLVMBuilder->getInt32(fieldIndex));
177}
178
179Value * IDISA_Builder::mvmd_dslli(unsigned fw, Value * a, Value * b, unsigned shift) {
180    unsigned field_count = mBitBlockWidth/fw;
181    Value * aVec = fwCast(fw, a);
182    Value * bVec = fwCast(fw, b);
183    std::vector<Constant*> Idxs;
184    for (unsigned i = shift; i < field_count + shift; i++) {
185        Idxs.push_back(mLLVMBuilder->getInt32(i));
186    }
187    return mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs));
188}
189
190Value * IDISA_Builder::bitblock_any(Value * a) {
191    Type * iBitBlock = mLLVMBuilder->getIntNTy(mBitBlockWidth);
192    return mLLVMBuilder->CreateICmpNE(mLLVMBuilder->CreateBitCast(a, iBitBlock),  ConstantInt::get(iBitBlock, 0));
193}
194
195Value * IDISA_Builder::simd_and(Value * a, Value * b) {
196    return a->getType() == b->getType() ? mLLVMBuilder->CreateAnd(a, b) : mLLVMBuilder->CreateAnd(bitBlockCast(a), bitBlockCast(b));
197}
198
199Value * IDISA_Builder::simd_or(Value * a, Value * b) {
200    return a->getType() == b->getType() ? mLLVMBuilder->CreateOr(a, b) : mLLVMBuilder->CreateOr(bitBlockCast(a), bitBlockCast(b));
201}
202   
203Value * IDISA_Builder::simd_xor(Value * a, Value * b) {
204    return a->getType() == b->getType() ? mLLVMBuilder->CreateXor(a, b) : mLLVMBuilder->CreateXor(bitBlockCast(a), bitBlockCast(b));
205}
206
207Value * IDISA_Builder::simd_not(Value * a) {
208    return simd_xor(a, Constant::getAllOnesValue(a->getType()));
209}
210
211}
Note: See TracBrowser for help on using the repository browser.