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

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

mergeh and mergel IDISA functions

File size: 5.1 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#include <iostream>
13
14using namespace IDISA;
15
16Value * IDISA_Builder::bitBlockCast(Value * a) {
17    return llvm_builder->CreateBitCast(a, mBitBlockType);
18}
19
20VectorType * IDISA_Builder::fwVectorType(unsigned fw) {
21    int fieldCount = mBitBlockSize/fw;
22    return VectorType::get(llvm_builder->getIntNTy(fw), fieldCount);
23}
24
25Value * IDISA_Builder::fwCast(unsigned fw, Value * a) {
26    return llvm_builder->CreateBitCast(a, fwVectorType(fw));
27}
28
29Value * IDISA_Builder::simd_add(unsigned fw, Value * a, Value * b) {
30    return bitBlockCast(llvm_builder->CreateAdd(fwCast(fw, a), fwCast(fw, b)));
31}
32
33Value * IDISA_Builder::simd_sub(unsigned fw, Value * a, Value * b) {
34    return bitBlockCast(llvm_builder->CreateSub(fwCast(fw, a), fwCast(fw, b)));
35}
36
37Value * IDISA_Builder::simd_mult(unsigned fw, Value * a, Value * b) {
38    return bitBlockCast(llvm_builder->CreateMul(fwCast(fw, a), fwCast(fw, b)));
39}
40
41Value * IDISA_Builder::simd_eq(unsigned fw, Value * a, Value * b) {
42    return bitBlockCast(llvm_builder->CreateSExt(llvm_builder->CreateICmpEQ(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
43}
44
45Value * IDISA_Builder::simd_gt(unsigned fw, Value * a, Value * b) {
46    return bitBlockCast(llvm_builder->CreateSExt(llvm_builder->CreateICmpSGT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
47}
48
49Value * IDISA_Builder::simd_ugt(unsigned fw, Value * a, Value * b) {
50    return bitBlockCast(llvm_builder->CreateSExt(llvm_builder->CreateICmpUGT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
51}
52
53Value * IDISA_Builder::simd_lt(unsigned fw, Value * a, Value * b) {
54    return bitBlockCast(llvm_builder->CreateSExt(llvm_builder->CreateICmpSLT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
55}
56
57Value * IDISA_Builder::simd_ult(unsigned fw, Value * a, Value * b) {
58    return bitBlockCast(llvm_builder->CreateSExt(llvm_builder->CreateICmpULT(fwCast(fw, a), fwCast(fw, b)), fwVectorType(fw)));
59}
60
61Value * IDISA_Builder::simd_max(unsigned fw, Value * a, Value * b) {
62    Value * aVec = fwCast(fw, a);
63    Value * bVec = fwCast(fw, b);
64    return bitBlockCast(llvm_builder->CreateSelect(llvm_builder->CreateICmpSGT(aVec, bVec), aVec, bVec));
65}
66
67Value * IDISA_Builder::simd_umax(unsigned fw, Value * a, Value * b) {
68    Value * aVec = fwCast(fw, a);
69    Value * bVec = fwCast(fw, b);
70    return bitBlockCast(llvm_builder->CreateSelect(llvm_builder->CreateICmpUGT(aVec, bVec), aVec, bVec));
71}
72
73Value * IDISA_Builder::simd_min(unsigned fw, Value * a, Value * b) {
74    Value * aVec = fwCast(fw, a);
75    Value * bVec = fwCast(fw, b);
76    return bitBlockCast(llvm_builder->CreateSelect(llvm_builder->CreateICmpSLT(aVec, bVec), aVec, bVec));
77}
78
79Value * IDISA_Builder::simd_umin(unsigned fw, Value * a, Value * b) {
80    Value * aVec = fwCast(fw, a);
81    Value * bVec = fwCast(fw, b);
82    return bitBlockCast(llvm_builder->CreateSelect(llvm_builder->CreateICmpULT(aVec, bVec), aVec, bVec));
83}
84
85Value * IDISA_Builder::simd_slli(unsigned fw, Value * a, unsigned shift) {
86    return bitBlockCast(llvm_builder->CreateShl(fwCast(fw, a), shift));
87}
88
89Value * IDISA_Builder::simd_srli(unsigned fw, Value * a, unsigned shift) {
90    return bitBlockCast(llvm_builder->CreateLShr(fwCast(fw, a), shift));
91}
92
93Value * IDISA_Builder::simd_srai(unsigned fw, Value * a, unsigned shift) {
94    return bitBlockCast(llvm_builder->CreateAShr(fwCast(fw, a), shift));
95}
96
97Value * IDISA_Builder::simd_cttz(unsigned fw, Value * a) {
98    Value * cttzFunc = Intrinsic::getDeclaration(mMod, Intrinsic::cttz, fwVectorType(fw));
99    Value * rslt = llvm_builder->CreateCall(cttzFunc, {fwCast(fw, a), ConstantInt::get(llvm_builder->getInt1Ty(), 0)});
100    return bitBlockCast(rslt);
101}
102
103Value * IDISA_Builder::esimd_mergeh(unsigned fw, Value * a, Value * b) {
104    unsigned field_count = mBitBlockSize/fw;
105    Value * aVec = fwCast(fw, a);
106    Value * bVec = fwCast(fw, b);
107    std::vector<Constant*> Idxs;
108    for (unsigned i = field_count/2; i < field_count; i++) {
109        Idxs.push_back(llvm_builder->getInt32(i));    // selects elements 1, 3, ... from first reg.
110        Idxs.push_back(llvm_builder->getInt32(i + field_count)); // selects elements 1, 3, ... from second reg.
111    }
112    return bitBlockCast(llvm_builder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
113}
114
115Value * IDISA_Builder::esimd_mergel(unsigned fw, Value * a, Value * b) {
116    unsigned field_count = mBitBlockSize/fw;
117    Value * aVec = fwCast(fw, a);
118    Value * bVec = fwCast(fw, b);
119    std::vector<Constant*> Idxs;
120    for (unsigned i = 0; i < field_count/2; i++) {
121        Idxs.push_back(llvm_builder->getInt32(i));    // selects elements 1, 3, ... from first reg.
122        Idxs.push_back(llvm_builder->getInt32(i + field_count)); // selects elements 1, 3, ... from second reg.
123    }
124    return bitBlockCast(llvm_builder->CreateShuffleVector(aVec, bVec, ConstantVector::get(Idxs)));
125}
126
127
128
Note: See TracBrowser for help on using the repository browser.