source: icGREP/icgrep-devel/icgrep/IDISA/s2p_gen.cpp @ 4903

Last change on this file since 4903 was 4900, checked in by cameron, 3 years ago

Dynamic generation of s2p code

File size: 3.9 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 */
5
6
7#include "s2p_gen.h"
8
9void s2p_step(IDISA::IDISA_Builder * iBuilder, Value * s0, Value * s1, Value * hi_mask, unsigned shift, Value * &p0, Value * &p1) {
10    Value * t0 = iBuilder->hsimd_packh(16, s0, s1);
11    Value * t1 = iBuilder->hsimd_packl(16, s0, s1);
12    p0 = iBuilder->simd_if(1, hi_mask, t0, iBuilder->simd_srli(16, t1, shift));
13    p1 = iBuilder->simd_if(1, hi_mask, iBuilder->simd_slli(16, t0, shift), t1);
14}
15
16void s2p(IDISA::IDISA_Builder * iBuilder, Value * s[], Value * p[]) {
17    Value * bit00224466[4];
18    Value * bit11335577[4];
19    for (unsigned i = 0; i<4; i++) {
20        s2p_step(iBuilder, s[2*i], s[2*i+1], iBuilder->simd_himask(2), 1, bit00224466[i], bit11335577[i]);
21    }
22    Value * bit00004444[2];
23    Value * bit22226666[2];
24    Value * bit11115555[2];
25    Value * bit33337777[2];
26    for (unsigned j = 0; j<2; j++) {
27        s2p_step(iBuilder, bit00224466[2*j], bit00224466[2*j+1],
28                 iBuilder->simd_himask(4), 2, bit00004444[j], bit22226666[j]);
29        s2p_step(iBuilder, bit11335577[2*j], bit11335577[2*j+1],
30                 iBuilder->simd_himask(4), 2, bit11115555[j], bit33337777[j]);
31    }
32    s2p_step(iBuilder, bit00004444[0], bit00004444[1], iBuilder->simd_himask(8), 4, p[0], p[4]);
33    s2p_step(iBuilder, bit11115555[0], bit11115555[1], iBuilder->simd_himask(8), 4, p[1], p[5]);
34    s2p_step(iBuilder, bit22226666[0], bit22226666[1], iBuilder->simd_himask(8), 4, p[2], p[6]);
35    s2p_step(iBuilder, bit33337777[0], bit33337777[1], iBuilder->simd_himask(8), 4, p[3], p[7]);
36}
37
38
39void gen_s2p_function(Module * m, IDISA::IDISA_Builder * iBuilder) {
40    Type * inputType = PointerType::get(iBuilder->getBitBlockType(), 0);
41    Type * outputType = PointerType::get(StructType::get(m->getContext(), std::vector<Type *>(8, iBuilder->getBitBlockType())), 0);
42    FunctionType * functionType = FunctionType::get(Type::getVoidTy(m->getContext()), std::vector<Type *>({inputType, outputType}), false);
43   
44    Function * sFunction;
45   
46    SmallVector<AttributeSet, 3> Attrs;
47    Attrs.push_back(AttributeSet::get(m->getContext(), ~0U, std::vector<Attribute::AttrKind>({ Attribute::NoUnwind, Attribute::UWTable })));
48    Attrs.push_back(AttributeSet::get(m->getContext(), 1U, std::vector<Attribute::AttrKind>({ Attribute::ReadOnly, Attribute::NoCapture })));
49    Attrs.push_back(AttributeSet::get(m->getContext(), 2U, std::vector<Attribute::AttrKind>({ Attribute::ReadNone, Attribute::NoCapture })));
50    AttributeSet AttrSet = AttributeSet::get(m->getContext(), Attrs);
51   
52    // Create the function that will be generated.
53    sFunction = Function::Create(functionType, GlobalValue::ExternalLinkage, "s2p_block", m);
54    sFunction->setCallingConv(CallingConv::C);
55    sFunction->setAttributes(AttrSet);
56   
57    Function::arg_iterator args = sFunction->arg_begin();
58    Value * inputAddressPtr = args++;
59    inputAddressPtr->setName("byte_data");
60    Value * outputAddressPtr = args++;
61    outputAddressPtr->setName("basis_bits");
62   
63   
64    iBuilder->SetInsertPoint(BasicBlock::Create(m->getContext(), "entry", sFunction,0));
65    Value * byte_pack[8];
66    Value * basis_bit[8];
67   
68    for (unsigned i = 0; i < 8; ++i) {
69        Value* indices[] = {iBuilder->getInt64(i)};
70        Value * gep = iBuilder->CreateGEP(inputAddressPtr, indices);
71        byte_pack[i] = iBuilder->CreateAlignedLoad(gep, iBuilder->getBitBlockWidth()/8, false, "byte_pack");
72    }
73
74    s2p(iBuilder, byte_pack, basis_bit);
75
76    //The basis bits structure (output)
77    for (unsigned i = 0; i < 8; ++i) {
78        Value* indices[] = {iBuilder->getInt64(0), iBuilder->getInt32(i)};
79        Value * gep = iBuilder->CreateGEP(outputAddressPtr, indices);
80        iBuilder->CreateAlignedStore(basis_bit[i], gep, iBuilder->getBitBlockWidth()/8, false);
81    }
82    iBuilder->CreateRetVoid();
83}
Note: See TracBrowser for help on using the repository browser.