source: icGREP/icgrep-devel/icgrep/kernels/u8u32_kernel.cpp

Last change on this file was 6184, checked in by nmedfort, 4 months ago

Initial version of PipelineKernel? + revised StreamSet? model.

File size: 8.5 KB
Line 
1/*
2 *  Copyright (c) 2016 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 */
5
6#include "u8u32_kernel.h"
7#include <re/re_cc.h>
8#include <pablo/pe_ones.h>          // for Ones
9#include <pablo/pe_var.h>           // for Var
10#include <pablo/pe_zeroes.h>        // for Zeroes
11#include <cc/cc_compiler.h>
12#include <pablo/builder.hpp>
13#include <llvm/IR/Module.h>
14#include <pablo/pablo_toolchain.h>                 // for pablo_function_passes
15
16using namespace kernel;
17using namespace pablo;
18using namespace llvm;
19
20void U8U32KernelBuilder::generatePabloMethod() {
21    PabloBuilder main(getEntryScope());
22   
23    //  input: 8 basis bit streams
24    std::vector<PabloAST *> u8_bits = getInputStreamSet("u8bit");
25    //  output: 32 u8-indexed streams, + delmask stream + error stream
26   
27    cc::Parabix_CC_Compiler ccc(getEntryScope(), u8_bits);
28   
29    Zeroes * zeroes = main.createZeroes();
30
31    // Outputs
32    // The first 11 bits of u32 are always 0s.
33
34    Var * u32_0[8];
35    for (int i = 0; i < 8; i++) {
36        u32_0[i] = main.createVar("u32_0" + std::to_string(i), zeroes);
37    }
38
39    Var * u32_1[8];
40    for (int i = 0; i < 8; i++) {
41        u32_1[i] = main.createVar("u32_1" + std::to_string(i), zeroes);
42    }
43   
44    Var * u32_2[8];
45    for (int i = 0; i < 8; i++) {
46        u32_2[i] = main.createVar("u32_2" + std::to_string(i), zeroes);
47    }
48   
49    Var * delmask = main.createVar("delmask", zeroes);
50    Var * error_mask = main.createVar("error_mask", zeroes);
51   
52    PabloAST * ASCII = ccc.compileCC("ASCII", re::makeByte(0x0, 0x7F), main);
53    auto ascii = main.createScope();
54    for (int i = 1; i <= 7; i++) {
55        ascii.createAssign(u32_2[i], ascii.createOr(u32_2[i], ascii.createAnd(ASCII, u8_bits[i])));
56    }
57    main.createIf(ASCII, ascii);
58   
59    PabloAST * u8pfx = ccc.compileCC("u8pfx", re::makeByte(0xC0, 0xFF), main);
60    PabloAST * nonASCII = ccc.compileCC("u8pfx", re::makeByte(0x80, 0xFF), main);
61    auto it = main.createScope();
62    main.createIf(nonASCII, it);
63   
64    Var * u8invalid = it.createVar("u8invalid", zeroes);
65    PabloAST * u8pfx2 = ccc.compileCC(re::makeByte(0xC2, 0xDF), it);
66    PabloAST * u8pfx3 = ccc.compileCC(re::makeByte(0xE0, 0xEF), it);
67    PabloAST * u8pfx4 = ccc.compileCC(re::makeByte(0xF0, 0xF4), it);
68    PabloAST * u8suffix = ccc.compileCC("u8suffix", re::makeByte(0x80, 0xBF), it);
69   
70    //
71   
72    //
73    // Two-byte sequences
74    Var * u8scope22 = it.createVar("u8scope22", zeroes);
75    auto it2 = it.createScope();
76    it.createIf(u8pfx2, it2);
77    it2.createAssign(u8scope22, it2.createAdvance(u8pfx2, 1));
78    //PabloAST * u8scope22 = it2.createAdvance(u8pfx2, 1, "u8scope22");
79    for (int i = 2; i <= 7; i++) {
80        it2.createAssign(u32_2[i], it2.createOr(u32_2[i], it2.createAnd(u8scope22, u8_bits[i])));
81    }
82    it2.createAssign(u32_2[1], it2.createOr(u32_2[1], it2.createAnd(u8scope22, it2.createAdvance(u8_bits[7], 1))));
83    it2.createAssign(u32_2[0], it2.createOr(u32_2[0], it2.createAnd(u8scope22, it2.createAdvance(u8_bits[6], 1))));
84    for (int i = 3; i <= 5; i++) {
85        it2.createAssign(u32_1[i + 2], it2.createOr(u32_1[i + 2], it2.createAnd(u8scope22, it2.createAdvance(u8_bits[i], 1))));
86    }
87   
88    //
89    // Three-byte sequences
90    Var * u8scope3X = it.createVar("u8scope3X", zeroes);
91    Var * EX_invalid = it.createVar("EX_invalid", zeroes);
92    Var * del3 = it.createVar("del3", zeroes);
93
94    auto it3 = it.createScope();
95    it.createIf(u8pfx3, it3);
96   
97    PabloAST * u8scope32 = it3.createAdvance(u8pfx3, 1, "u8scope32");
98    PabloAST * u8scope33 = it3.createAdvance(u8scope32, 1, "u8scope33");
99    it3.createAssign(u8scope3X, it3.createOr(u8scope32, u8scope33));
100    PabloAST * E0_invalid = it3.createAnd(it3.createAdvance(ccc.compileCC(re::makeByte(0xE0), it3), 1), ccc.compileCC(re::makeByte(0x80, 0x9F), it3));
101    PabloAST * ED_invalid = it3.createAnd(it3.createAdvance(ccc.compileCC(re::makeByte(0xED), it3), 1), ccc.compileCC(re::makeByte(0xA0, 0xBF), it3));
102    it3.createAssign(EX_invalid, it3.createOr(E0_invalid, ED_invalid));
103   
104    for (int i = 2; i <= 7; i++) {
105        it3.createAssign(u32_2[i], it3.createOr(u32_2[i], it3.createAnd(u8scope33, u8_bits[i])));
106    }
107    it3.createAssign(u32_2[1], it3.createOr(u32_2[1], it3.createAnd(u8scope33, it3.createAdvance(u8_bits[7], 1))));
108    it3.createAssign(u32_2[0], it3.createOr(u32_2[0], it3.createAnd(u8scope33, it3.createAdvance(u8_bits[6], 1))));
109    for (int i = 2; i <= 5; i++) {
110        it3.createAssign(u32_1[i + 2], it3.createOr(u32_1[i + 2], it3.createAnd(u8scope33, it3.createAdvance(u8_bits[i], 1))));
111    }
112    for (int i = 4; i <= 7; i++) {
113        it3.createAssign(u32_1[i - 4], it3.createOr(u32_1[i - 4], it3.createAnd(u8scope33, it3.createAdvance(u8_bits[i], 2))));
114    }
115    it3.createAssign(del3, u8scope32);
116
117    //
118    // Four-byte sequences
119    Var * u8scope4nonfinal = it.createVar("u8scope4nonfinal", zeroes);
120    Var * u8scope4X = it.createVar("u8scope4X", zeroes);
121    Var * FX_invalid = it.createVar("FX_invalid", zeroes);
122    Var * del4 = it.createVar("del4", zeroes);
123   
124    auto it4 = it.createScope();
125    it.createIf(u8pfx4, it4);
126    PabloAST * u8scope42 = it4.createAdvance(u8pfx4, 1, "u8scope42");
127    PabloAST * u8scope43 = it4.createAdvance(u8scope42, 1, "u8scope43");
128    PabloAST * u8scope44 = it4.createAdvance(u8scope43, 1, "u8scope44");
129
130   
131    it4.createAssign(u8scope4nonfinal, it4.createOr(u8scope42, u8scope43));
132    it4.createAssign(u8scope4X, it4.createOr(u8scope4nonfinal, u8scope44));
133    PabloAST * F0_invalid = it4.createAnd(it4.createAdvance(ccc.compileCC(re::makeByte(0xF0), it4), 1), ccc.compileCC(re::makeByte(0x80, 0x8F), it4));
134    PabloAST * F4_invalid = it4.createAnd(it4.createAdvance(ccc.compileCC(re::makeByte(0xF4), it4), 1), ccc.compileCC(re::makeByte(0x90, 0xBF), it4));
135    it4.createAssign(FX_invalid, it4.createOr(F0_invalid, F4_invalid));
136
137
138    for (int i = 2; i <= 7; i++) {
139        it4.createAssign(u32_2[i], it4.createOr(u32_2[i], it4.createAnd(u8scope44, u8_bits[i])));
140    }
141    it4.createAssign(u32_2[1], it4.createOr(u32_2[1], it4.createAnd(u8scope44, it4.createAdvance(u8_bits[7], 1))));
142    it4.createAssign(u32_2[0], it4.createOr(u32_2[0], it4.createAnd(u8scope44, it4.createAdvance(u8_bits[6], 1))));
143    for (int i = 2; i <= 5; i++) {
144        it4.createAssign(u32_1[i + 2], it4.createOr(u32_1[i + 2], it4.createAnd(u8scope44, it4.createAdvance(u8_bits[i], 1))));
145    }
146    for (int i = 4; i <= 7; i++) {
147        it4.createAssign(u32_1[i - 4], it4.createOr(u32_1[i - 4], it4.createAnd(u8scope44, it4.createAdvance(u8_bits[i], 2))));
148    }
149    it4.createAssign(u32_0[7], it4.createOr(u32_0[7], it4.createAnd(u8scope44, it4.createAdvance(u8_bits[3], 2))));
150    it4.createAssign(u32_0[6], it4.createOr(u32_0[6], it4.createAnd(u8scope44, it4.createAdvance(u8_bits[2], 2))));
151    for (int i = 5; i <= 7; i++) {
152        it4.createAssign(u32_0[i - 2], it4.createOr(u32_0[i - 2], it4.createAnd(u8scope44, it4.createAdvance(u8_bits[i], 3))));
153    }
154       
155    it4.createAssign(del4, it4.createOr(u8scope42, u8scope43));
156   
157    //
158    // Invalid cases
159    PabloAST * anyscope = it.createOr(u8scope22, it.createOr(u8scope3X, u8scope4X), "anyscope");
160    PabloAST * legalpfx = it.createOr(it.createOr(u8pfx2, u8pfx3), u8pfx4);
161    //  Any scope that does not have a suffix byte, and any suffix byte that is not in
162    //  a scope is a mismatch, i.e., invalid UTF-8.
163    PabloAST * mismatch = it.createXor(anyscope, u8suffix);
164    //
165    PabloAST * EF_invalid = it.createOr(EX_invalid, FX_invalid);
166    PabloAST * pfx_invalid = it.createXor(u8pfx, legalpfx);
167    it.createAssign(u8invalid, it.createOr(pfx_invalid, it.createOr(mismatch, EF_invalid)));
168    //PabloAST * u8valid = it.createNot(u8invalid, "u8valid");
169    it.createAssign(error_mask, u8invalid);
170   
171    it.createAssign(delmask, it.createOr(it.createOr(del3, del4), ccc.compileCC(re::makeByte(0xC0, 0xFF), it)));
172   
173    Var * output = getOutputStreamVar("u32bit");
174    Var * delmask_out = getOutputStreamVar("delMask");
175    Var * error_mask_out = getOutputStreamVar("errMask");
176   
177
178    for (unsigned i = 0; i < 8; i++) {
179        main.createAssign(main.createExtract(output, i), u32_0[i]);
180    }
181    for (unsigned i = 0; i < 8; i++) {
182        main.createAssign(main.createExtract(output, i + 8), u32_1[i]);
183    }
184    for (unsigned i = 0; i < 8; i++) {
185        main.createAssign(main.createExtract(output, i + 16), u32_2[i]);
186    }
187    main.createAssign(main.createExtract(delmask_out, main.getInteger(0)), delmask);
188    main.createAssign(main.createExtract(error_mask_out,  main.getInteger(0)), error_mask);
189
190}
Note: See TracBrowser for help on using the repository browser.