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

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

Further progress on Carry Manager with bit packing

File size: 7.0 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 = mBitBlockSize/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, {fwCast(fw, a), ConstantInt::get(mLLVMBuilder->getInt1Ty(), 0)});
99    return bitBlockCast(rslt);
100}
101
102Value * IDISA_Builder::esimd_mergeh(unsigned fw, Value * a, Value * b) {
103    unsigned field_count = mBitBlockSize/fw;
104    Value * aVec = fwCast(fw, a);
105    Value * bVec = fwCast(fw, b);
106    std::vector<Constant*> Idxs;
107    for (unsigned i = field_count/2; i < field_count; i++) {
108        Idxs.push_back(mLLVMBuilder->getInt32(i));    // selects elements from first reg.
109        Idxs.push_back(mLLVMBuilder->getInt32(i + field_count)); // selects elements from second reg.
110    }
111    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
112}
113
114Value * IDISA_Builder::esimd_mergel(unsigned fw, Value * a, Value * b) {
115    unsigned field_count = mBitBlockSize/fw;
116    Value * aVec = fwCast(fw, a);
117    Value * bVec = fwCast(fw, b);
118    std::vector<Constant*> Idxs;
119    for (unsigned i = 0; i < field_count/2; i++) {
120        Idxs.push_back(mLLVMBuilder->getInt32(i));    // selects elements from first reg.
121        Idxs.push_back(mLLVMBuilder->getInt32(i + field_count)); // selects elements from second reg.
122    }
123    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
124}
125
126Value * IDISA_Builder::hsimd_packh(unsigned fw, Value * a, Value * b) {
127    unsigned field_count = 2 * mBitBlockSize/fw;
128    Value * aVec = fwCast(fw/2, a);
129    Value * bVec = fwCast(fw/2, b);
130    std::vector<Constant*> Idxs;
131    for (unsigned i = 0; i < field_count; i++) {
132        Idxs.push_back(mLLVMBuilder->getInt32(2*i));
133    }
134    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
135}
136
137Value * IDISA_Builder::hsimd_packl(unsigned fw, Value * a, Value * b) {
138    unsigned field_count = 2 * mBitBlockSize/fw;
139    Value * aVec = fwCast(fw/2, a);
140    Value * bVec = fwCast(fw/2, b);
141    std::vector<Constant*> Idxs;
142    for (unsigned i = 0; i < field_count; i++) {
143        Idxs.push_back(mLLVMBuilder->getInt32(2*i+1));
144    }
145    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
146}
147
148Value * IDISA_Builder::hsimd_signmask(unsigned fw, Value * a) {
149    Value * mask = mLLVMBuilder->CreateICmpSLT(fwCast(fw, a), ConstantAggregateZero::get(fwVectorType(fw)));
150    return mLLVMBuilder->CreateBitCast(mask, mLLVMBuilder->getIntNTy(mBitBlockSize/fw));
151}
152
153Value * IDISA_Builder::mvmd_extract(unsigned fw, Value * a, unsigned fieldIndex) {
154    Value * aVec = fwCast(fw, a);
155    return mLLVMBuilder->CreateExtractElement(aVec, mLLVMBuilder->getInt32(fieldIndex));
156}
157
158Value * IDISA_Builder::mvmd_dslli(unsigned fw, Value * a, Value * b, unsigned shift) {
159    unsigned field_count = mBitBlockSize/fw;
160    Value * aVec = fwCast(fw, a);
161    Value * bVec = fwCast(fw, b);
162    std::vector<Constant*> Idxs;
163    for (unsigned i = shift; i < field_count + shift; i++) {
164        Idxs.push_back(mLLVMBuilder->getInt32(i));
165    }
166    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
167}
168
169Value * IDISA_Builder::bitblock_any(Value * a) {
170    Type * iBitBlock = mLLVMBuilder->getIntNTy(mBitBlockSize);
171    return mLLVMBuilder->CreateICmpNE(mLLVMBuilder->CreateBitCast(a, iBitBlock),  ConstantInt::get(iBitBlock, 0));
172}
173
174}
Note: See TracBrowser for help on using the repository browser.