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

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

Parameterize carry_manager to inherit BitBlockWidth? from idisa builder

File size: 7.3 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 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 mLLVMBuilder->CreateBitCast(a, fwVectorType(fw));
26}
27
28Value * IDISA_Builder::simd_add(unsigned fw, Value * a, Value * b) {
29    return bitBlockCast(mLLVMBuilder->CreateAdd(fwCast(fw, a), fwCast(fw, b)));
30}
31
32Value * IDISA_Builder::simd_sub(unsigned fw, Value * a, Value * b) {
33    return bitBlockCast(mLLVMBuilder->CreateSub(fwCast(fw, a), fwCast(fw, b)));
34}
35
36Value * IDISA_Builder::simd_mult(unsigned fw, Value * a, Value * b) {
37    return bitBlockCast(mLLVMBuilder->CreateMul(fwCast(fw, a), fwCast(fw, b)));
38}
39
40Value * IDISA_Builder::simd_eq(unsigned fw, Value * a, Value * b) {
41    return bitBlockCast(mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpEQ(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
42}
43
44Value * IDISA_Builder::simd_gt(unsigned fw, Value * a, Value * b) {
45    return bitBlockCast(mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpSGT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
46}
47
48Value * IDISA_Builder::simd_ugt(unsigned fw, Value * a, Value * b) {
49    return bitBlockCast(mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpUGT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
50}
51
52Value * IDISA_Builder::simd_lt(unsigned fw, Value * a, Value * b) {
53    return bitBlockCast(mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpSLT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
54}
55
56Value * IDISA_Builder::simd_ult(unsigned fw, Value * a, Value * b) {
57    return bitBlockCast(mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpULT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
58}
59
60Value * IDISA_Builder::simd_max(unsigned fw, Value * a, Value * b) {
61    Value * aVec = fwCast(fw, a);
62    Value * bVec = fwCast(fw, b);
63    return bitBlockCast(mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpSGT(aVec, bVec), aVec, bVec));
64}
65
66Value * IDISA_Builder::simd_umax(unsigned fw, Value * a, Value * b) {
67    Value * aVec = fwCast(fw, a);
68    Value * bVec = fwCast(fw, b);
69    return bitBlockCast(mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpUGT(aVec, bVec), aVec, bVec));
70}
71
72Value * IDISA_Builder::simd_min(unsigned fw, Value * a, Value * b) {
73    Value * aVec = fwCast(fw, a);
74    Value * bVec = fwCast(fw, b);
75    return bitBlockCast(mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpSLT(aVec, bVec), aVec, bVec));
76}
77
78Value * IDISA_Builder::simd_umin(unsigned fw, Value * a, Value * b) {
79    Value * aVec = fwCast(fw, a);
80    Value * bVec = fwCast(fw, b);
81    return bitBlockCast(mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpULT(aVec, bVec), aVec, bVec));
82}
83
84Value * IDISA_Builder::simd_slli(unsigned fw, Value * a, unsigned shift) {
85    return bitBlockCast(mLLVMBuilder->CreateShl(fwCast(fw, a), shift));
86}
87
88Value * IDISA_Builder::simd_srli(unsigned fw, Value * a, unsigned shift) {
89    return bitBlockCast(mLLVMBuilder->CreateLShr(fwCast(fw, a), shift));
90}
91
92Value * IDISA_Builder::simd_srai(unsigned fw, Value * a, unsigned shift) {
93    return bitBlockCast(mLLVMBuilder->CreateAShr(fwCast(fw, a), shift));
94}
95
96Value * IDISA_Builder::simd_cttz(unsigned fw, Value * a) {
97    Value * cttzFunc = Intrinsic::getDeclaration(mMod, Intrinsic::cttz, fwVectorType(fw));
98    Value * rslt = mLLVMBuilder->CreateCall(cttzFunc, std::vector<Value *>({fwCast(fw, a), ConstantInt::get(mLLVMBuilder->getInt1Ty(), 0)}));
99    return bitBlockCast(rslt);
100}
101
102Value * IDISA_Builder::simd_popcount(unsigned fw, Value * a) {
103    Value * ctpopFunc = Intrinsic::getDeclaration(mMod, Intrinsic::ctpop, fwVectorType(fw));
104    Value * rslt = mLLVMBuilder->CreateCall(ctpopFunc, std::vector<Value *>({fwCast(fw, a)}));
105    return bitBlockCast(rslt);
106}
107
108Value * IDISA_Builder::esimd_mergeh(unsigned fw, Value * a, Value * b) {
109    unsigned field_count = mBitBlockWidth/fw;
110    Value * aVec = fwCast(fw, a);
111    Value * bVec = fwCast(fw, b);
112    std::vector<Constant*> Idxs;
113    for (unsigned i = field_count/2; i < field_count; i++) {
114        Idxs.push_back(mLLVMBuilder->getInt32(i));    // selects elements from first reg.
115        Idxs.push_back(mLLVMBuilder->getInt32(i + field_count)); // selects elements from second reg.
116    }
117    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
118}
119
120Value * IDISA_Builder::esimd_mergel(unsigned fw, Value * a, Value * b) {
121    unsigned field_count = mBitBlockWidth/fw;
122    Value * aVec = fwCast(fw, a);
123    Value * bVec = fwCast(fw, b);
124    std::vector<Constant*> Idxs;
125    for (unsigned i = 0; i < field_count/2; i++) {
126        Idxs.push_back(mLLVMBuilder->getInt32(i));    // selects elements from first reg.
127        Idxs.push_back(mLLVMBuilder->getInt32(i + field_count)); // selects elements from second reg.
128    }
129    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
130}
131
132Value * IDISA_Builder::hsimd_packh(unsigned fw, Value * a, Value * b) {
133    unsigned field_count = 2 * mBitBlockWidth/fw;
134    Value * aVec = fwCast(fw/2, a);
135    Value * bVec = fwCast(fw/2, b);
136    std::vector<Constant*> Idxs;
137    for (unsigned i = 0; i < field_count; i++) {
138        Idxs.push_back(mLLVMBuilder->getInt32(2*i));
139    }
140    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
141}
142
143Value * IDISA_Builder::hsimd_packl(unsigned fw, Value * a, Value * b) {
144    unsigned field_count = 2 * mBitBlockWidth/fw;
145    Value * aVec = fwCast(fw/2, a);
146    Value * bVec = fwCast(fw/2, b);
147    std::vector<Constant*> Idxs;
148    for (unsigned i = 0; i < field_count; i++) {
149        Idxs.push_back(mLLVMBuilder->getInt32(2*i+1));
150    }
151    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
152}
153
154Value * IDISA_Builder::hsimd_signmask(unsigned fw, Value * a) {
155    Value * mask = mLLVMBuilder->CreateICmpSLT(fwCast(fw, a), ConstantAggregateZero::get(fwVectorType(fw)));
156    return mLLVMBuilder->CreateBitCast(mask, mLLVMBuilder->getIntNTy(mBitBlockWidth/fw));
157}
158
159Value * IDISA_Builder::mvmd_extract(unsigned fw, Value * a, unsigned fieldIndex) {
160    Value * aVec = fwCast(fw, a);
161    return mLLVMBuilder->CreateExtractElement(aVec, mLLVMBuilder->getInt32(fieldIndex));
162}
163
164Value * IDISA_Builder::mvmd_dslli(unsigned fw, Value * a, Value * b, unsigned shift) {
165    unsigned field_count = mBitBlockWidth/fw;
166    Value * aVec = fwCast(fw, a);
167    Value * bVec = fwCast(fw, b);
168    std::vector<Constant*> Idxs;
169    for (unsigned i = shift; i < field_count + shift; i++) {
170        Idxs.push_back(mLLVMBuilder->getInt32(i));
171    }
172    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
173}
174
175Value * IDISA_Builder::bitblock_any(Value * a) {
176    Type * iBitBlock = mLLVMBuilder->getIntNTy(mBitBlockWidth);
177    return mLLVMBuilder->CreateICmpNE(mLLVMBuilder->CreateBitCast(a, iBitBlock),  ConstantInt::get(iBitBlock, 0));
178}
179
180}
Note: See TracBrowser for help on using the repository browser.