source: icGREP/icgrep-devel/icgrep/kernels/hex_convert.cpp @ 6161

Last change on this file since 6161 was 6058, checked in by cameron, 17 months ago

Small fixes

File size: 4.7 KB
Line 
1/*
2 *  Copyright (c) 2018 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
5
6#include "hex_convert.h"
7#include <kernels/kernel_builder.h>
8#include <llvm/IR/Module.h>
9#include <llvm/Support/raw_ostream.h>
10
11using namespace kernel;
12using namespace llvm;
13
14HexToBinary::HexToBinary(const std::unique_ptr<kernel::KernelBuilder> & b)
15: BlockOrientedKernel("HexToBinary",
16                   {Binding{b->getStreamSetTy(1, 8), "hexdata", FixedRate()}},
17                   {Binding{b->getStreamSetTy(1, 1), "binary_data", FixedRate(4)}},
18{}, {}, {}) {}
19
20void HexToBinary::generateDoBlockMethod(const std::unique_ptr<KernelBuilder> & b) {
21    Type * i8Ty = b->getInt8Ty();
22    Constant * const ZERO = b->getSize(0);
23    const unsigned bytesPerBlock = b->getBitBlockWidth()/8;
24    Constant * splat_0 = ConstantVector::getSplat(bytesPerBlock, ConstantInt::get(i8Ty, '0'));
25    Constant * splat_9 = ConstantVector::getSplat(bytesPerBlock, ConstantInt::get(i8Ty, '9'));
26    Constant * case_shift = ConstantVector::getSplat(bytesPerBlock, ConstantInt::get(i8Ty, 'a' - 'A'));
27    Constant * splat_a = ConstantVector::getSplat(bytesPerBlock, ConstantInt::get(i8Ty, 'a'));
28    Constant * splat_f = ConstantVector::getSplat(bytesPerBlock, ConstantInt::get(i8Ty, 'f'));
29    Constant * af_cvt = ConstantVector::getSplat(bytesPerBlock, ConstantInt::get(i8Ty, 'a' - 10));
30
31    for (unsigned i = 0; i < 4; i++) {
32        Value * hexPack[2];
33        hexPack[0] = b->loadInputStreamPack("hexdata", ZERO, b->getInt32(2*i));
34        hexPack[1] = b->loadInputStreamPack("hexdata", ZERO, b->getInt32(2*i + 1));
35        Value * base_val[2];
36        for (unsigned j = 0; j < 2; j++) {
37            Value * lc_hex = b->simd_or(hexPack[j], case_shift); // valid only for [A-Za-z]=>[a-z]
38            Value * range_09 = b->simd_and(b->simd_ule(8, splat_0, hexPack[j]), b->simd_ule(8, hexPack[j], splat_9));
39            Value * range_af = b->simd_and(b->simd_ule(8, splat_a, lc_hex), b->simd_ule(8, lc_hex, splat_f));
40            base_val[j] = b->simd_or(b->simd_and(range_09, b->simd_sub(8, hexPack[j], splat_0)),
41                                    b->simd_and(range_af, b->simd_sub(8, lc_hex, af_cvt)));
42        }
43        //b->CallPrintInt("binary_pack ptr", b->CreateGEP(outputStreamBasePtr, b->CreateUDiv(packNumPhi, TWO)));
44        Value * binary_pack = b->bitCast(b->hsimd_packl(8, base_val[0], base_val[1]));
45        b->storeOutputStreamBlock("binary_data", ZERO, b->getSize(i), binary_pack); 
46    }
47}
48
49BinaryToHex::BinaryToHex(const std::unique_ptr<kernel::KernelBuilder> & b)
50: BlockOrientedKernel("BinaryToHex",
51                   {Binding{b->getStreamSetTy(1, 1), "binary_data", FixedRate(4)}},
52                   {Binding{b->getStreamSetTy(1, 8), "hexdata", FixedRate(), RoundUpTo(1)}},
53                   {}, {}, {}) {}
54
55
56void BinaryToHex::generateDoBlockMethod(const std::unique_ptr<KernelBuilder> & b) {
57    Type * i8Ty = b->getInt8Ty();
58    Constant * const ZERO = b->getSize(0);
59    const unsigned bytesPerBlock = b->getBitBlockWidth()/8;
60    Constant * splatCh_0 = ConstantVector::getSplat(bytesPerBlock, ConstantInt::get(i8Ty, '0'));
61    Constant * splat_9 = ConstantVector::getSplat(bytesPerBlock, ConstantInt::get(i8Ty, 9));
62    Constant * splatCh_a = ConstantVector::getSplat(bytesPerBlock, ConstantInt::get(i8Ty, 'a'-10));
63    for (unsigned i = 0; i < 4; i++) {
64        Value * bit_data = b->loadInputStreamBlock("binary_data", ZERO, b->getInt32(i));
65        Value * nybble_0 = b->fwCast(8, b->esimd_mergel(4, bit_data, b->allZeroes()));
66        Value * nybble_1 = b->fwCast(8, b->esimd_mergeh(4, bit_data, b->allZeroes()));
67        Value * data_09 = b->simd_add(8, nybble_0, splatCh_0);
68        Value * data_af = b->simd_add(8, nybble_0, splatCh_a);
69        Value * hex_data = b->bitCast(b->CreateSelect(b->CreateICmpULE(nybble_0, splat_9), data_09, data_af));
70        b->storeOutputStreamPack("hexdata", ZERO, b->getInt32(2*i), hex_data);
71        data_09 = b->simd_add(8, nybble_1, splatCh_0);
72        data_af = b->simd_add(8, nybble_1, splatCh_a);
73        hex_data = b->bitCast(b->CreateSelect(b->CreateICmpULE(nybble_1, splat_9), data_09, data_af));
74        b->storeOutputStreamPack("hexdata", ZERO, b->getInt32(2*i + 1), hex_data);
75    }
76}
77
78void BinaryToHex::generateFinalBlockMethod(const std::unique_ptr<KernelBuilder> & b, Value * const remainingBits) {
79    Value * priorProduced = b->getProducedItemCount("hexdata");
80    CreateDoBlockMethodCall(b);
81    Value * remainingHexDigits = b->CreateUDiv(b->CreateAdd(remainingBits, b->getSize(3)), b->getSize(4));
82    Value * toZero = b->CreateSub(b->getSize(b->getBitBlockWidth()), remainingHexDigits);
83    b->CreateMemZero(b->getRawOutputPointer("hexdata", b->CreateAdd(priorProduced, remainingHexDigits)), toZero);
84}
Note: See TracBrowser for help on using the repository browser.