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

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

Implementatation of the Pablo Count operation

File size: 7.2 KB
RevLine 
[4651]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
[4665]13namespace IDISA {
[4651]14
15Value * IDISA_Builder::bitBlockCast(Value * a) {
[4665]16    return mLLVMBuilder->CreateBitCast(a, mBitBlockType);
[4651]17}
18
19VectorType * IDISA_Builder::fwVectorType(unsigned fw) {
20    int fieldCount = mBitBlockSize/fw;
[4665]21    return VectorType::get(mLLVMBuilder->getIntNTy(fw), fieldCount);
[4651]22}
23
24Value * IDISA_Builder::fwCast(unsigned fw, Value * a) {
[4665]25    return mLLVMBuilder->CreateBitCast(a, fwVectorType(fw));
[4651]26}
27
28Value * IDISA_Builder::simd_add(unsigned fw, Value * a, Value * b) {
[4665]29    return bitBlockCast(mLLVMBuilder->CreateAdd(fwCast(fw, a), fwCast(fw, b)));
[4651]30}
31
32Value * IDISA_Builder::simd_sub(unsigned fw, Value * a, Value * b) {
[4665]33    return bitBlockCast(mLLVMBuilder->CreateSub(fwCast(fw, a), fwCast(fw, b)));
[4651]34}
35
36Value * IDISA_Builder::simd_mult(unsigned fw, Value * a, Value * b) {
[4665]37    return bitBlockCast(mLLVMBuilder->CreateMul(fwCast(fw, a), fwCast(fw, b)));
[4651]38}
39
40Value * IDISA_Builder::simd_eq(unsigned fw, Value * a, Value * b) {
[4665]41    return bitBlockCast(mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpEQ(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
[4651]42}
43
44Value * IDISA_Builder::simd_gt(unsigned fw, Value * a, Value * b) {
[4665]45    return bitBlockCast(mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpSGT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
[4651]46}
47
48Value * IDISA_Builder::simd_ugt(unsigned fw, Value * a, Value * b) {
[4665]49    return bitBlockCast(mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpUGT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
[4651]50}
51
52Value * IDISA_Builder::simd_lt(unsigned fw, Value * a, Value * b) {
[4665]53    return bitBlockCast(mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpSLT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
[4651]54}
55
56Value * IDISA_Builder::simd_ult(unsigned fw, Value * a, Value * b) {
[4665]57    return bitBlockCast(mLLVMBuilder->CreateSExt(mLLVMBuilder->CreateICmpULT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
[4651]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);
[4665]63    return bitBlockCast(mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpSGT(aVec, bVec), aVec, bVec));
[4651]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);
[4665]69    return bitBlockCast(mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpUGT(aVec, bVec), aVec, bVec));
[4651]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);
[4665]75    return bitBlockCast(mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpSLT(aVec, bVec), aVec, bVec));
[4651]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);
[4665]81    return bitBlockCast(mLLVMBuilder->CreateSelect(mLLVMBuilder->CreateICmpULT(aVec, bVec), aVec, bVec));
[4651]82}
83
84Value * IDISA_Builder::simd_slli(unsigned fw, Value * a, unsigned shift) {
[4665]85    return bitBlockCast(mLLVMBuilder->CreateShl(fwCast(fw, a), shift));
[4651]86}
87
88Value * IDISA_Builder::simd_srli(unsigned fw, Value * a, unsigned shift) {
[4665]89    return bitBlockCast(mLLVMBuilder->CreateLShr(fwCast(fw, a), shift));
[4651]90}
91
92Value * IDISA_Builder::simd_srai(unsigned fw, Value * a, unsigned shift) {
[4665]93    return bitBlockCast(mLLVMBuilder->CreateAShr(fwCast(fw, a), shift));
[4651]94}
95
96Value * IDISA_Builder::simd_cttz(unsigned fw, Value * a) {
97    Value * cttzFunc = Intrinsic::getDeclaration(mMod, Intrinsic::cttz, fwVectorType(fw));
[4665]98    Value * rslt = mLLVMBuilder->CreateCall(cttzFunc, {fwCast(fw, a), ConstantInt::get(mLLVMBuilder->getInt1Ty(), 0)});
[4651]99    return bitBlockCast(rslt);
100}
101
[4720]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, {fwCast(fw, a)});
105    return bitBlockCast(rslt);
106}
107
[4652]108Value * IDISA_Builder::esimd_mergeh(unsigned fw, Value * a, Value * b) {
109    unsigned field_count = mBitBlockSize/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++) {
[4665]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.
[4652]116    }
[4665]117    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
[4652]118}
119
120Value * IDISA_Builder::esimd_mergel(unsigned fw, Value * a, Value * b) {
121    unsigned field_count = mBitBlockSize/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++) {
[4665]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.
[4652]128    }
[4665]129    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
[4652]130}
131
[4653]132Value * IDISA_Builder::hsimd_packh(unsigned fw, Value * a, Value * b) {
133    unsigned field_count = 2 * mBitBlockSize/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++) {
[4665]138        Idxs.push_back(mLLVMBuilder->getInt32(2*i));
[4653]139    }
[4665]140    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
[4653]141}
[4652]142
[4653]143Value * IDISA_Builder::hsimd_packl(unsigned fw, Value * a, Value * b) {
144    unsigned field_count = 2 * mBitBlockSize/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++) {
[4665]149        Idxs.push_back(mLLVMBuilder->getInt32(2*i+1));
[4653]150    }
[4665]151    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
[4653]152}
[4652]153
[4653]154Value * IDISA_Builder::hsimd_signmask(unsigned fw, Value * a) {
[4665]155    Value * mask = mLLVMBuilder->CreateICmpSLT(fwCast(fw, a), ConstantAggregateZero::get(fwVectorType(fw)));
156    return mLLVMBuilder->CreateBitCast(mask, mLLVMBuilder->getIntNTy(mBitBlockSize/fw));
[4653]157}
158
[4697]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
[4655]164Value * IDISA_Builder::mvmd_dslli(unsigned fw, Value * a, Value * b, unsigned shift) {
165    unsigned field_count = mBitBlockSize/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++) {
[4665]170        Idxs.push_back(mLLVMBuilder->getInt32(i));
[4655]171    }
[4665]172    return bitBlockCast(mLLVMBuilder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
[4655]173}
[4653]174
[4662]175Value * IDISA_Builder::bitblock_any(Value * a) {
[4665]176    Type * iBitBlock = mLLVMBuilder->getIntNTy(mBitBlockSize);
177    return mLLVMBuilder->CreateICmpNE(mLLVMBuilder->CreateBitCast(a, iBitBlock),  ConstantInt::get(iBitBlock, 0));
[4662]178}
[4665]179
180}
Note: See TracBrowser for help on using the repository browser.