source: proto/u8u16/pablo_template.cpp @ 1822

Last change on this file since 1822 was 1822, checked in by cameron, 7 years ago

Updating for basis bit structs

File size: 11.4 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <errno.h>
4#include <string.h>
5#include <sys/types.h>
6#include <sys/stat.h>
7
8#define LocalCarryDeclare(name, count)\
9CarryArray<count> name;\
10
11#include "../lib/bitblock.hpp"
12#include "../lib/carryQ.hpp"
13#include "../lib/s2p.hpp"
14#include "../lib/p2s.hpp"
15
16#define minimum(x,y) ((x) <(y) ?(x) :(y) )
17#include <iostream>
18using namespace std;
19
20#include "../lib/perflib/perfsec.h"
21
22// Profiling
23#if (defined(BUFFER_PROFILING) || defined(CODE_CLOCKER))
24  #include "../lib/perflib/perfsec.h"
25#endif
26
27#ifdef BUFFER_PROFILING
28BOM_Table * transcode_timer;
29#endif
30
31#define SEGMENT_BLOCKS 10
32
33#ifdef CODE_CLOCKER
34        #define NUM_EVENTS 1
35        int Events[NUM_EVENTS] = {PAPI_TOT_CYC};
36        //int Events[NUM_EVENTS] = {PAPI_L2_DCM};
37        //int Events[NUM_EVENTS] = {PAPI_TOT_CYC, PAPI_BR_MSP};
38        int cal_size = 20;
39        CC * transcode_timer = new CC(Events,NUM_EVENTS,cal_size);
40#endif
41
42/*===========================================================================*/
43/* UErrorCode */
44/* Extracted from ICU */
45/*===========================================================================*/
46
47typedef enum UErrorCode {
48
49    U_ZERO_ERROR              =  0,     /**< No error, no warning. */
50    U_TRUNCATED_CHAR_FOUND    = 11,     /**< Character conversion: Incomplete input sequence. */
51    U_ILLEGAL_CHAR_FOUND      = 12,     /**< Character conversion: Illegal input sequence/combination of input units. */
52} UErrorCode;
53
54typedef  uint16_t UChar;
55
56
57#define do_right8_shifts(vec, rshift1, rshift2, rshift4) \
58do { BitBlock s2; \
59  vec = simd<8>::sub(vec, simd<16>::srli<1>(simd_and(rshift1, vec))); \
60  s2 = simd_and(rshift2, vec);\
61  vec = simd_or(simd<16>::srli<2>(s2), simd_xor(vec, s2));\
62  s2 = simd_and(rshift4, vec);\
63  vec = simd_or(simd<16>::srli<4>(s2), simd_xor(vec, s2));\
64} while(0)
65
66static inline void del_info_8(BitBlock &del8_rshift1, BitBlock &del8_rshift2, BitBlock &del8_rshift4, BitBlock delmask){
67        BitBlock del8_trans2;
68        BitBlock del8_trans4;
69        BitBlock shift_bits;
70       
71        del8_rshift1 = simd_xor(simd<8>::slli<1>(delmask), simd<8>::slli<2>(delmask));
72        del8_rshift1 = simd_xor(del8_rshift1, simd<8>::slli<2>(del8_rshift1));
73        del8_rshift1 = simd_xor(del8_rshift1, simd<8>::slli<4>(del8_rshift1));
74        /* Transition to even delcount: odd delcount to left, this one deleted. */
75        del8_trans2 = simd_and(del8_rshift1, delmask);
76        /* Odd number of transition positions to left. */
77        del8_rshift2 = simd_xor(simd<8>::slli<1>(del8_trans2), simd<8>::slli<2>(del8_trans2));
78        del8_rshift2 = simd_xor(del8_rshift2, simd<8>::slli<2>(del8_rshift2));
79        del8_rshift2 = simd_xor(del8_rshift2, simd<8>::slli<4>(del8_rshift2));
80        /* Transition positions: odd |del2count| to left, this one a transition to even. */
81        del8_trans4 = simd_and(del8_rshift2, del8_trans2);
82        del8_rshift4 = simd_xor(simd<8>::slli<1>(del8_trans4), simd<8>::slli<2>(del8_trans4));
83        del8_rshift4 = simd_xor(del8_rshift4, simd<8>::slli<2>(del8_rshift4));
84        del8_rshift4 = simd_xor(del8_rshift4, simd<8>::slli<4>(del8_rshift4));
85        /* Only move bits that are not deleted. */
86        del8_rshift1 = simd_andc(del8_rshift1, delmask);
87        del8_rshift2 = simd_andc(del8_rshift2, delmask);
88        del8_rshift4 = simd_andc(del8_rshift4, delmask);
89        /* Update |del8_rshift2| to apply after |del8_rshift1|. */
90        del8_rshift2 = simd<8>::sub(del8_rshift2, simd<16>::srli<1>(simd_and(del8_rshift1, del8_rshift2)));
91        /* Update |del8_rshift4| to apply after |del8_rshift2| and |del8_rshift1|. */
92        del8_rshift4 = simd<8>::sub(del8_rshift4, simd<16>::srli<1>(simd_and(del8_rshift1, del8_rshift4)));
93        shift_bits = simd_and(del8_rshift2, del8_rshift4);
94        del8_rshift4 = simd_or(simd<16>::srli<4>(shift_bits), simd_xor(del8_rshift4, shift_bits));
95}
96
97
98static inline void del_count(BitBlock delmask, BitBlock & u16_units_per_reg){
99
100        BitBlock delcounts_8 = simd<8>::popcount(delmask);
101        u16_units_per_reg = simd<8>::sub(simd<8>::constant<8>(), delcounts_8);
102}
103
104
105#define BUFFER_SIZE (BLOCK_SIZE * 100)
106
107@global
108
109void u8u16(UChar ** targetbuf, const UChar * targetlimit, char ** srcbuf, const char * srclimit, UErrorCode * err){
110
111  @decl
112
113
114  BytePack U8s[8];
115  BytePack U16h[8];
116  BytePack U16l[8];
117  BytePack U16s[16];
118
119  BitBlock EOF_mask = simd<1>::constant<1>();
120
121
122  int pos = 0;
123
124  bool error_found = false;
125  int err_pos;
126
127  @stream_stmts
128
129       
130    while (((*srcbuf) < srclimit) || @any_carry ){
131     
132      int u8advance = minimum(srclimit-(*srcbuf),BLOCK_SIZE);
133
134      if(u8advance < BLOCK_SIZE){
135        EOF_mask = bitblock::srl(simd<1>::constant<1>(), convert(BLOCK_SIZE-u8advance));
136
137      }
138      else
139        EOF_mask = simd<1>::constant<1>();
140     
141      BytePack * U8pack = (BytePack *) (*srcbuf);
142      U8s[0] = bitblock::load_unaligned(&U8pack[0]);
143      U8s[1] = bitblock::load_unaligned(&U8pack[1]);
144      U8s[2] = bitblock::load_unaligned(&U8pack[2]);
145      U8s[3] = bitblock::load_unaligned(&U8pack[3]);
146      U8s[4] = bitblock::load_unaligned(&U8pack[4]);
147      U8s[5] = bitblock::load_unaligned(&U8pack[5]);
148      U8s[6] = bitblock::load_unaligned(&U8pack[6]);
149      U8s[7] = bitblock::load_unaligned(&U8pack[7]); 
150     
151      s2p(U8s[0], U8s[1], U8s[2], U8s[3], U8s[4], U8s[5], U8s[6], U8s[7],
152          u8_bits.bit_0, u8_bits.bit_1, u8_bits.bit_2, u8_bits.bit_3, u8_bits.bit_4, u8_bits.bit_5, u8_bits.bit_6, u8_bits.bit_7);
153
154        u8_bits.bit_0 = simd_and(u8_bits.bit_0, EOF_mask);
155        u8_bits.bit_1 = simd_and(u8_bits.bit_1, EOF_mask);
156        u8_bits.bit_2 = simd_and(u8_bits.bit_2, EOF_mask);
157        u8_bits.bit_3 = simd_and(u8_bits.bit_3, EOF_mask);
158        u8_bits.bit_4 = simd_and(u8_bits.bit_4, EOF_mask);
159        u8_bits.bit_5 = simd_and(u8_bits.bit_5, EOF_mask);
160        u8_bits.bit_6 = simd_and(u8_bits.bit_6, EOF_mask);
161        u8_bits.bit_7 = simd_and(u8_bits.bit_7, EOF_mask);
162   
163      @block_stmts
164     
165      u8.delmask |= ~EOF_mask;
166      error_found = bitblock::any(u8.error);
167      if (error_found) {
168        int errpos = count_forward_zeroes(u8.error);
169        if (errpos >= u8advance) {
170          *err = U_TRUNCATED_CHAR_FOUND;
171        }
172        else *err = U_ILLEGAL_CHAR_FOUND;
173        BitBlock cutoff_mask = bitblock::sll(simd<1>::constant<1>(), convert(errpos));
174        BitBlock errbit = simd_andc(u8.error, bitblock::slli<1>(cutoff_mask));
175        u8advance = errpos;
176        if (bitblock::any(simd_and(u8.scope44, errbit))) {
177          u8advance -= 3;
178          /* May have already first of a surrogate pair to targetbuf. */
179          if (u8advance == -3) *targetbuf -= 1;
180        }
181        else if (bitblock::any(simd_and(u8.scope43, errbit))) {
182          u8advance -= 2;
183        }
184        else if (bitblock::any(simd_and(u8.scope33, errbit))) {
185          u8advance -= 2;
186        }
187        else if (bitblock::any(simd_and(simd_or(u8.scope22, simd_or(u8.scope32, u8.scope42)), errbit))) {
188          u8advance -= 1;
189        }
190        if (u8advance <= 0) {
191          (*srcbuf) += u8advance;
192          return;
193        }
194        u8.delmask |= bitblock::sll(simd<1>::constant<1>(), convert(u8advance));
195//      fprintf(stderr, "errpos = %i, u8advance = %i\n", errpos, u8advance);
196      }
197     
198       
199      if (bitblock::any(u8.delmask)) {
200              BitBlock shift1, shift2, shift4;
201              del_info_8(shift1, shift2, shift4, u8.delmask);
202              do_right8_shifts(u16lo.bit_0, shift1, shift2, shift4);
203              do_right8_shifts(u16lo.bit_1, shift1, shift2, shift4);
204              do_right8_shifts(u16lo.bit_2, shift1, shift2, shift4);
205              do_right8_shifts(u16lo.bit_3, shift1, shift2, shift4);
206              do_right8_shifts(u16lo.bit_4, shift1, shift2, shift4);
207              do_right8_shifts(u16lo.bit_5, shift1, shift2, shift4);
208              do_right8_shifts(u16lo.bit_6, shift1, shift2, shift4);
209              do_right8_shifts(u16lo.bit_7, shift1, shift2, shift4);
210              if (bitblock::any(u8.scope33 | u8.surrogate)) {
211                      do_right8_shifts(u16hi.bit_0, shift1, shift2, shift4);
212                      do_right8_shifts(u16hi.bit_1, shift1, shift2, shift4);
213                      do_right8_shifts(u16hi.bit_2, shift1, shift2, shift4);
214                      do_right8_shifts(u16hi.bit_3, shift1, shift2, shift4);
215                      do_right8_shifts(u16hi.bit_4, shift1, shift2, shift4);
216              }
217              do_right8_shifts(u16hi.bit_5, shift1, shift2, shift4);
218              do_right8_shifts(u16hi.bit_6, shift1, shift2, shift4);
219              do_right8_shifts(u16hi.bit_7, shift1, shift2, shift4);
220      }
221
222      union {BitBlock i128; uint8_t i8[16];} u16_units_per_reg;
223     
224      p2s(u16lo.bit_0,u16lo.bit_1,u16lo.bit_2,u16lo.bit_3,u16lo.bit_4,u16lo.bit_5,u16lo.bit_6,u16lo.bit_7,
225                        U16l[0], U16l[1],U16l[2] ,U16l[3] ,U16l[4] ,U16l[5] ,U16l[6] ,U16l[7]);
226      p2s(u16hi.bit_0,u16hi.bit_1,u16hi.bit_2,u16hi.bit_3,u16hi.bit_4,u16hi.bit_5,u16hi.bit_6,u16hi.bit_7,
227                        U16h[0], U16h[1],U16h[2] ,U16h[3] ,U16h[4] ,U16h[5] ,U16h[6] ,U16h[7]);
228      for (int i=0; i<8; i++) {
229        U16s[2*i] = esimd<8>::mergel(U16l[i], U16h[i]);
230        U16s[2*i+1] = esimd<8>::mergeh(U16l[i], U16h[i]);
231      }
232       
233      for(int k=0; k<16; k++) u16_units_per_reg.i8[k] = 0;
234      del_count(u8.delmask,u16_units_per_reg.i128);
235
236      for(int j=0; j<16; j++){
237        bitblock::store_unaligned(U16s[j], (BitBlock *) (*targetbuf));
238        *targetbuf += u16_units_per_reg.i8[j];
239      }
240
241      (*srcbuf) += u8advance;
242         
243      if (error_found) return;
244    }
245    *err = U_ZERO_ERROR;
246}
247
248
249void do_process(FILE *infile, FILE *outfile) {
250
251  int buf_pos = 0;
252  int bytes_available = 0;
253  int excess_bytes, i;
254  char srcbuf[BUFFER_SIZE+BLOCK_SIZE];
255  char * srclimit;
256  UChar targetbuf[BUFFER_SIZE+BLOCK_SIZE];
257  UChar * targetlimit;
258  UChar * targetbuf_start;
259  UChar * targetbuf_ptr=targetbuf;
260  char * srcbuf_ptr=srcbuf;
261  UErrorCode status;
262 
263  bytes_available = fread((void *)srcbuf, sizeof(char), BUFFER_SIZE, infile);
264  srclimit = srcbuf + bytes_available;
265  targetbuf_start = targetbuf;
266
267  while(bytes_available>0){
268
269    PERF_SEC_START(transcode_timer);
270       
271    srcbuf_ptr=srcbuf;
272    targetbuf_ptr=targetbuf;
273
274    u8u16(&targetbuf_ptr, targetlimit, &srcbuf_ptr, srclimit, &status); 
275    excess_bytes = (int) (srclimit - srcbuf_ptr);
276    buf_pos += bytes_available - excess_bytes;
277
278    PERF_SEC_END(transcode_timer, bytes_available - excess_bytes);
279   
280   
281    fwrite(targetbuf_start , sizeof(UChar) ,  targetbuf_ptr - targetbuf_start, outfile );
282   
283    if (status == U_ILLEGAL_CHAR_FOUND) {
284            fclose(infile);
285            fclose(outfile);
286            fprintf(stderr, "Illegal UTF-8 sequence at position %lu in source.\n", (unsigned long) buf_pos);
287            exit(-1);
288    }
289    else if (status == U_TRUNCATED_CHAR_FOUND) {
290        for (i = 0; i < excess_bytes; i++) {
291          srcbuf[i] = srcbuf_ptr[i];
292        }
293        bytes_available = fread((void *) &(srcbuf[excess_bytes]), sizeof(char), BUFFER_SIZE-excess_bytes, infile);
294        if (bytes_available == 0) {
295            fclose(infile);
296            fclose(outfile);
297            fprintf(stderr, "EOF with incomplete UTF-8 sequence at position %lu in source.\n", (unsigned long) buf_pos);
298            exit(-1);
299        }
300        bytes_available += excess_bytes;
301        srclimit = srcbuf + bytes_available;
302    }
303    else {
304      bytes_available = fread((void *)srcbuf, sizeof(char), BUFFER_SIZE, infile);
305      srclimit = srcbuf + bytes_available;
306    }
307  }
308}
309
310
311
312int
313main(int argc, char * argv[]) {
314        char * infilename, * outfilename;       
315        FILE *infile, *outfile;
316
317        if (argc < 2) {
318                printf("Usage: %s <filename> [<outputfile>]\n", argv[0]);
319                exit(-1);
320        }
321
322        infilename = argv[1];
323        infile = fopen(infilename, "rb");
324        if (!infile) {
325                fprintf(stderr, "Error: cannot open %s for input.\n", infilename);
326                exit(-1);
327        }
328       
329        if (argc < 3) outfile = stdout;
330        else {
331                outfilename = argv[2];
332                outfile = fopen(outfilename, "wb");
333                if (!outfile) {
334                        fprintf(stderr, "Error: cannot open %s for writing.\n", outfilename);
335                        exit(-1);
336                }
337        }
338
339
340        PERF_SEC_INIT(transcode_timer);
341
342        do_process(infile, outfile);
343       
344        PERF_SEC_DUMP(transcode_timer);
345
346        PERF_SEC_DESTROY(transcode_timer);     
347       
348        fclose(infile);
349        fclose(outfile);
350        return(0);
351}
Note: See TracBrowser for help on using the repository browser.